JDBC框架入门及DBUtils的入门
一、【数据库元数据的获取】(做框架用时非常实用)主要有以下java接口(都在java.sql.*包中):
1>DataBaseMetaData 数据库元数据
元数据:数据库本身及表结构、字段类型等的信息,称之为元数据。
好处:获取一些数据库的信息,比如数据库方言,数据库版本,建表的一些信息等。
如:DatabaseMetaData md = conn.getMetaData();然后可用md.getDatabaseProductName
2>ParameterMetaData 可获取 PreparedStatement 对象中每个参数标记的类型和属性信息的对象
如: ParameterMetaData md = stmt.getParameterMetaData();
md.getParameterCount() 获取参数?的个数。
md.getParameterTypeName(int index) 获取指定参数对应数据库中的类型名称。
等等。
3>ResultSetMetaData 可获取ResultSet 对象中列的类型和属性信息的对象。
如:ResultSetMetaData md = rs.getMetaData();
int count = md.getColumnCount(); 获取结果集中存在几列。
md.getColumnName(int index); 获取指定列的列名名称。
md.getColumnTypeName(int column); 获取指定列的数据库特定的类型名称。
等等。
二、【自定义框架原理】
1>可通过上面的三个元数据类,获取比如参数的个数。将需要执行的sql与参数数组传递进框架中,然后通过PrepardeStatment stmt=conn.preparedStatement(sql);获取到stmt对象。那么通过stmt.getParameterMetaData().getParameterCount()获取到参数的个数后,可以写相关的循环,用stmt.setObject(index,arg[i])分别设置好参数。直接executeUpdate或executeQuery即可。
对于DML语句来说,是用executeUpdate方法执行的,所以不需要返回值,基本上一个核心方法即可搞定。
2>而对于DQL语句来说,Select出来的结果集,可以被封装成多个不同类型的java对象。所以可以在执行rs = stmt.executeQuery();(注意前面的设置参数也是上面的提成的,直接用ParameterMetaDate获取的参数个数后,循环分别将数组中元素用setObject搞定),然后可将rs作为参数传递到ResultSetHandler接口的handler方法中。此handler方法返回Object类型,由用户自行去实现ResultSetHandler接口,这样用户可以对rs处理后,封装成自己想要的对象。
3>当然为了方便实现框架最好提供默认的BeanHandler(Class clazz)类的实现,此类对handler方法的实现只是将rs结果集封装成传递到BeanHandler类构造参数的clazz类实例中。
4>同理还需要提供一个常用的BeanListHandler(Class clazz)类实现,将rs结果集先封装成指定clazz的javabean中,再将这些javabean全部放入到List容器中。(以上两个方法必须要用反射实现)。
三、【开源jdbc框架DBUtils】 是apache提供一个优秀的jdbc框架,原理就是上面自定义框架原理。
核心类QueryRunner
1、有2个构造方法,需要一个 javax.sql.DataSource 来作参数的构造方法,通过这个数据源,来获取Connection
2、QueryRunner主要方法有2个 query和update。来分别提供对DQL与DML语句的支持。
3、对于查询到的结果集,提供了一个接口 ResultSetHandler
框架中提供了以下对ResultSetHandler接口实现的类
ArrayHandler:将查询到的某一行封装到一个数组当中,这个数组中的元素就是这一行中的一列
ArrayListHandler:将查询到的很多行结果,封装到一个容器当中,这个容器中存放都是数组
BeanHandler:将查询到的结果封装到javaBean中 在创建这个对象的时候,需要指定javaBean的type(ClassName.Class)
BeanListHandler:将查询到的很多javaBean封装到一个容器中
ColumnListHandler: 将结果集中某一列的数据存放到List中。 创建对象的时候,参数需要指定列名
将结果集中的每一行数据都封装到一个Map<列名,列值>里,
再把这些map再存到一个大map里,小map的key作为大map的key
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
ScalarHandler:取一行中的某一列的值。(用于select count(*) from ...)
示例代码如下: public class ResultHandlerDemo { //获取QueryRunner对象。 private QueryRunner qr = new QueryRunner(DbcpUtil.getDataSource()); @Test public void test1() throws SQLException{ String sql = "select * from person where id=?"; Object params = 1; Person person = qr.query(sql, new BeanHandler<Person>(Person.class), params);//执行DQL,用query System.out.println(person); } @Test public void test2() throws SQLException{ String sql = "delete from person where id=?"; Object params = 1; qr.update(sql, params);//执行DML,用update } }