7、利用泛型和反射,让public static T findById(Class clazz, int id)方法,更具一般性

1、前面讲到的findById(int id),只是一个仅仅针对user表的操作,为了使得查找方法更具有一般性,引入了泛型和反射

2、利用泛型和反射,让public static <T> T findById(Class<T> clazz, int id)方法,更具一般性.GenericityJDBCUtils的代码如下

package com.jdbc.genericity.utils;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.jdbc.entity.User;
import com.jdbc.utils.MyJDBCUtils;

public class GenericityJDBCUtils {

	private static Connection conn;
	private static PreparedStatement pstate;
	private static ResultSet rs;
	// 为了程序的更好的解耦合,利用Properties文件保存连接Mysql的配置文件
	private static Properties config = new Properties();
	/**
	 * 使用static块,加载数据库的配置文件和数据库的驱动
	 */
	static {
		try {
			config.load(MyJDBCUtils.class.getClassLoader().getResourceAsStream(
					"db.properties"));
			Class.forName(config.getProperty("driver"));
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	/**
	 * 获取一个数据库的连接
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		Connection conn = null;
		try {
			conn = DriverManager.getConnection(config.getProperty("url"),
					config.getProperty("username"),
					config.getProperty("password"));
		} catch (SQLException e) {
			throw new RuntimeException("获取连接Mysql数据库连接失败");
		}
		return conn;
	}

	/**
	 * 释放数据库的连接
	 * 
	 * @param conn
	 * @param st
	 * @param rs
	 */
	public static void release(Connection conn, Statement st, ResultSet rs) {

		if (rs != null) {
			try {
				rs.close();
			} catch (Exception e) {
				throw new RuntimeException("ResultSet关闭异常");
			}
			rs = null;
		}
		if (st != null) {
			try {
				st.close();
			} catch (Exception e) {
				throw new RuntimeException("Statement关闭异常");
			}
			st = null;
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (Exception e) {
				throw new RuntimeException("Connection关闭异常");
			}
			conn = null;
		}

	}

	/**
	 * 
	 * @param clazz
	 *            要返回的类型的字节码
	 * @param id
	 *            要查找记录在表里面的id
	 * @return 在数据库里面查找到的记录,并返回
	 */
	public static <T> T findById(Class<T> clazz, int id) {
		T bean = null;
		// System.out.println(clazz.getSimpleName());
		try {
			bean = clazz.newInstance();
			String tableName = clazz.getSimpleName();
			String sql = "select * from " + tableName + " where id = ? ";
			conn = getConnection();
			pstate = conn.prepareStatement(sql);
			pstate.setInt(1, id);
			rs = pstate.executeQuery();
			if (rs.next()) {
				// 得到结果集的元数组
				ResultSetMetaData metaData = rs.getMetaData();
				int count = metaData.getColumnCount();
				for (int i = 0; i < count; i++) {
					// 注意jdbc的下标,从1开始
					// 去获取到数据库中的列的名称
					String name = metaData.getColumnName(i + 1);
					// 获取到,数据库列对应的数值
					Object value = rs.getObject(name);
					// 反射bean上与列名相同的属性
					Field f = bean.getClass().getDeclaredField(name);
					f.setAccessible(true);
					f.set(bean, value);
				}

			}
			return bean;

		} catch (Exception e) {
			throw new RuntimeException("在数据库中,查找id为" + id + "的User记录失败." + e);
		} finally {
			// 释放资源,关闭与数据库的连接
			release(conn, pstate, rs);
		}

	}

	/**
	 * 根据传进来的sql语句,来跟新数据库的表记录
	 * 
	 * @param sql
	 * @param args
	 */
	public static void update(String sql, Object[] args) {
		try {
			if (args.length < 0) {
				throw new RuntimeException("Object[] args的数组长度,不应该为空");
			}
			conn = getConnection();
			pstate = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				pstate.setObject(i + 1, args[i]);
			}
			// 注意要调用这个方法
			pstate.executeUpdate();
			// 释放资源,关闭与数据库的连接
			release(conn, pstate, rs);
		} catch (Exception e) {
			throw new RuntimeException("更新数据库中的记录失败" + e);
		}
	}

	/**
	 * 根据sql语句来更新数据库表中的记录
	 * 
	 * @param sql
	 */
	public static void update(String sql) {
		try {
			conn = getConnection();
			pstate = conn.prepareStatement(sql);
			// 注意要调用这个方法
			pstate.executeUpdate();
			// 释放资源,关闭与数据库的连接
			release(conn, pstate, rs);
		} catch (Exception e) {
			throw new RuntimeException("更新数据库中的记录失败" + e);
		}
	}

}
3、测试代码如下

package com.jdbc.genericity.test;

import org.junit.Test;

import com.jdbc.entity.Person;
import com.jdbc.entity.User;
import com.jdbc.genericity.utils.GenericityJDBCUtils;

public class GenericityJDBCUtilsTest {

	@Test
	public void tenericityJDBCUtilsTest() {
		User user = GenericityJDBCUtils.findById(User.class, 1);
		System.out.println(user);
		Person person = GenericityJDBCUtils.findById(Person.class, 1);
		System.out.println(person);

	}

}

3、数据库的情况

7、利用泛型和反射,让public static <T> T findById(Class<T> clazz, int id)方法,更具一般性_第1张图片

7、利用泛型和反射,让public static <T> T findById(Class<T> clazz, int id)方法,更具一般性_第2张图片

4、程序运行结果如下

7、利用泛型和反射,让public static <T> T findById(Class<T> clazz, int id)方法,更具一般性_第3张图片






你可能感兴趣的:(jdbc,泛型,id,findByIdint,jdbc连接mysql数据库)