日期:2014-05-16  浏览次数:20429 次

关于对JDBC操作偷懒的思考

可能都想过封装jdbc达到简化开发代码、提高开发效率,于是我也想弄这么一个框架,天马行空的思考开始了,

主要针对简单而常用的的CRUD操作。

?

  1. 首先,我想简化的是开发者输入一sql我就能封装好查询结果,返回给开发者,也类似于开发者如下调用

?

?

/**
	 * @author:lyjilu
	 * @throws Exception
	 */
	public List<Row> findAll() throws Exception {
		return super.findAll("select * from pop_dep");
	}
?

?

就能取得查询的结果,Row表示每一行,具体查询代码块如下:

?

/**
	 * @author:lyjilu
	 * @param conn 数据库连接 @param sql 要查询的sql
	 * @throws Exception
	 */
	public static List<Row> find(Connection conn, String sql) {
		long t1 = System.currentTimeMillis();
		ResultSet rs = null;
		PreparedStatement ps = null;
		List<Row> list = null;
		try {
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			int numberOfColumns = rsmd.getColumnCount();
			Map<String, ColumnMeta> map = new HashMap<String, ColumnMeta>();
			for (int i = 0; i < numberOfColumns; i++) {
				ColumnMeta columnMata = new ColumnMeta(
						rsmd.getColumnLabel(i + 1), 0,
						rsmd.getColumnType(i + 1),
						rsmd.getColumnTypeName(i + 1));
				map.put(rsmd.getColumnLabel(i + 1), columnMata);
			}
			String label = null;
			int type = 0;
			list = new ArrayList<Row>();
			while (rs.next()) {
				Row row = new Row();
				for (int i = 0; i < numberOfColumns; i++) {
					label = rsmd.getColumnLabel(i + 1);
					type = rsmd.getColumnType(i + 1);
					Object obj = DaoUtil.getObjectByName(rs, label, type);
					row.put(label, obj);
				}
				row.setColumnMetaMap(map);
				list.add(row);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			DaoUtil.closeDao(rs, ps, conn);
		}
		long t2 = System.currentTimeMillis();
		System.out.println(t2 - t1);
		return list;

	}

?

?其中几个类:ColumnMeta 是简单的类似于ResultSetMetaData 类,

而Row是一个组合了HashMap的类,getObjectByName方法则是通过不同类型取得值的方法

看似查询方法这样封装就已经差不多了,由于本文主要是思考,所以具体代码就简化了。那么下面就想怎么添加和修改呢

?

?

2.添加或修改

?

由于不能确定用户输入的值插入到哪表,

?

第一考虑是用户输入表名,查询一次表,就能取得表的字段及字段类型等信息,然后设置进去,进行添加操作,由于这样会每次添加会查询一次数据库,并且,还得让开发者指定要插入的表,不够合理,抛弃

?

第二考虑是用户定义实体类,和数据库一一对应,用户传递过来的就是要保存的实体,那么就可以进行保存操作,可考虑到这里的时候,又不得不考虑几个问题,

1>用户传递过来的实体名,字段名,是不是和表中的一致,不一致会有问题,

2>设置值的时候,如果实体中是String,那么就必须用PreparedStatement.setString()等,综上,那么就必须要求开发者的实体名,字段,必须和数据库一一对应,并且字段类型也必须设置正确等,如果稍不留神,就将出错。

?

第三考虑是在第二考虑基础上,增加配置,即,实体对应数据中的哪表,字段对应什么类型等等。最后保存的时候查询配置文件中的定义,就能较好的完成添加或修改操作,但是这样就增加了开发者配置实体和数据库对应关系的工作量。,说到这里,是不是觉得挺熟悉,这不就是简化版的Hibernate吗?

?

如果真的实现成第三考虑方案那样,那就会考虑到与数据库无关性,可能就是这样,HQL产生了吧,然后考虑到表间关系的复杂性,简化用户手动关联查询,于是在实体里面,就把外键关联的实体用Set(一对多是是Set<多的一方实体>)或另外的实体关联起来,于是就形成了查询一次全部查出吧,但是由于性能问题,就出现了LAZY ?懒加载用以在不使用的情况下不查询出关联数据,以提高性能。

?

最后没去实现了添加修改,毕竟那基本就是Hibernate

?

为了防盗,注上本文地址原始地址:http://lyjilu.iteye.com/blog/1162171

?