编辑自己的JDBC框架

编辑自己的JDBC框架

元数据

  • 在jdbc中获取数据库的定义,例如:数据库、表、列的定义信息。就用到元数据。
  • 在jdbc中可以使用: 数据库元数据、参数元数据、结果集元数据
  • (元数据定义相关api, ..MetaData)
public class App {

	//1. 数据库元数据
	@Test
	public void testDB() throws Exception {
		// 获取连接
		Connection conn = JdbcUtil.getConnection();
		// 获取数据库元数据
		DatabaseMetaData metaData = conn.getMetaData();// alt + shift + L  快速获取方法返回值
		
		System.out.println(metaData.getUserName());
		System.out.println(metaData.getURL());
		System.out.println(metaData.getDatabaseProductName());
	}
	
	//2. 参数元数据
	@Test
	public void testParams() throws Exception {
		// 获取连接
		Connection conn = JdbcUtil.getConnection();
		// SQL
		String sql = "select * from dept where deptid=? and deptName=?";
		// Object[] values = {"tom","888"};
		
		PreparedStatement pstmt = conn.prepareStatement(sql);
		// 参数元数据
		ParameterMetaData p_metaDate = pstmt.getParameterMetaData();
		// 获取参数的个数
		int count = p_metaDate.getParameterCount();
		
		
		// 测试
		System.out.println(count);
	}
	
	// 3. 结果集元数据
	@Test
	public void testRs() throws Exception {
		String sql = "select * from dept ";
		
		// 获取连接
		Connection conn = JdbcUtil.getConnection();
		PreparedStatement pstmt = conn.prepareStatement(sql);
		ResultSet rs = pstmt.executeQuery();
		// 得到结果集元数据(目标:通过结果集元数据,得到列的名称)
		ResultSetMetaData rs_metaData = rs.getMetaData();
		
		// 迭代每一行结果
		while (rs.next()) {
			// 1. 获取列的个数
			int count = rs_metaData.getColumnCount();
			// 2. 遍历,获取每一列的列的名称
			for (int i=0; i<count; i++) {
				// 得到列的名称
				String columnName = rs_metaData.getColumnName(i + 1);
				// 获取每一行的每一列的值
				Object columnValue = rs.getObject(columnName);
				// 测试
				System.out.print(columnName + "=" + columnValue + ",");
			}
			System.out.println();
		}
		
	}
	
	
	
}

使用元数据封装简单的JDBC框架

封装通用的update方法和qurey方法

public class JdbcUtils {

	private static DataSource ds = null;

	static {
		try {
			InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
			Properties prop = new Properties();
			prop.load(in);

			BasicDataSourceFactory factory = new BasicDataSourceFactory();

			ds = factory.createDataSource(prop);
			System.out.println(ds);
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}

	public static Connection getConnection() throws SQLException {

		return ds.getConnection();
	}

	public static void release(Connection conn, Statement st, ResultSet rs) {


		if (rs != null) {
			try {
				rs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			rs = null;

		}
		if (st != null) {
			try {
				st.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

		if (conn != null) {
			try {
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
	}

	//替换dao中的增删改方法
	public static void update(String sql, Object params[]) throws SQLException {
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;

		try {
			conn = getConnection();
			st = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				st.setObject(i + 1, params[i]);
			}
			st.executeUpdate();

		} finally {
			release(conn, st, rs);
		}
	}

	//替换所有dao中的查询   策略模式
	public static Object query(String sql, Object params[], ResultSetHandler rsh) throws SQLException {

		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;

		try {
			conn = getConnection();
			st = conn.prepareStatement(sql);
			for (int i = 0; i < params.length; i++) {
				st.setObject(i + 1, params[i]);
			}
			rs = st.executeQuery();
			return rsh.handler(rs);

		} finally {
			release(conn, st, rs);
		}
	}
}

集处理器接口ResultSetHandler

在设计query方法时,对于查询返回的结果集处理使用到了策略模式,query方法事先是无法知道用户对返回的查询结果集如何进行处理的,即不知道结果集的处理策略, 那么这个结果集的处理策略就让用户自己提供,query方法内部就调用用户提交的结果集处理策略进行处理, 为了能够让用户提供结果集的处理策略,需要对用户暴露出一个结果集处理接口ResultSetHandler, 结果集处理器接口ResultSetHandler的定义如下:

public interface ResultSetHandler {
	public Object handler(ResultSet rs);
}

编写常用的结果集处理器

为了提高框架的易用性,我们可以事先就针对结果集写好一些常用的处理器,比如将结果集转换成bean对象的处理器,将结果集转换成bean对象的list集合的处理器。

  • BeanHandler——将结果集转换成bean对象的处理器
public class BeanHandler implements ResultSetHandler {
	private Class clazz;
	public BeanHandler(Class clazz){
		this.clazz = clazz;
	}
	public Object handler(ResultSet rs) {
		try{
			if(!rs.next()){
				return null;
			}
			Object bean = clazz.newInstance();
			
			ResultSetMetaData metadata = rs.getMetaData();
			int columnCount = metadata.getColumnCount();  //得到有几列数据
			for(int i=0;i<columnCount;i++){
				String coulmnName = metadata.getColumnName(i+1);  //得到列名
				Object coulmnData = rs.getObject(i+1);
			}
		}
	}
}
  • BeanListHandler——将结果集转换成bean对象的list集合的处理器
public class BeanListHandler implements ResultSetHandler {
	private Class clazz;
	public BeanListHandler(Class clazz){
		this.clazz = clazz;
	}
	
	public Object handler(ResultSet rs) {
		try{
			List list = new ArrayList();
			while(rs.next()){
				Object bean = clazz.newInstance();
				
				ResultSetMetaData  metadata = rs.getMetaData();
				int count = metadata.getColumnCount();
				for(int i=0;i<count;i++){
					String name = metadata.getColumnName(i+1);
					Object value = rs.getObject(name);
					
					Field f = bean.getClass().getDeclaredField(name);
					f.setAccessible(true);
					f.set(bean, value);
				}
				list.add(bean);
			}
			return list.size()>0?list:null;
		
		}catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值