JDBC框架入门及DBUtils的入门

12年前

一、【数据库元数据的获取】(做框架用时非常实用)主要有以下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])分别设置好参数。直接executeUpdateexecuteQuery即可。

对于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结果集先封装成指定clazzjavabean中,再将这些javabean全部放入到List容器中。(以上两个方法必须要用反射实现)

三、【开源jdbc框架DBUtils】  是apache提供一个优秀的jdbc框架,原理就是上面自定义框架原理。

核心类QueryRunner

1、有2个构造方法,需要一个 javax.sql.DataSource 来作参数的构造方法,通过这个数据源,来获取Connection
2QueryRunner主要方法有2个  queryupdate。来分别提供对DQLDML语句的支持。

3、对于查询到的结果集,提供了一个接口 ResultSetHandler

框架中提供了以下对ResultSetHandler接口实现的类

ArrayHandler:将查询到的某一行封装到一个数组当中,这个数组中的元素就是这一行中的一列

ArrayListHandler:将查询到的很多行结果,封装到一个容器当中,这个容器中存放都是数组

BeanHandler:将查询到的结果封装到javaBean 在创建这个对象的时候,需要指定javaBeantype(ClassName.Class)

BeanListHandler:将查询到的很多javaBean封装到一个容器中

ColumnListHandler将结果集中某一列的数据存放到List中。    创建对象的时候,参数需要指定列名

KeyedHandler

将结果集中的每一行数据都封装到一个Map<列名,列值>里,

再把这些map再存到一个大map里,小mapkey作为大mapkey

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     }    }