从JDBC到commons-DBUtils

1.JDBC的使用

  1、添加驱动获取数据库连接

  2、创建ProperedStatement连接

  3、执行SQL语句并处理返回结果

  4、释放资源

String username="root";
String password="123";
String url="jdbc:mysql://localhost/test";
Connection con=null;
Statement st=null;
ResultSet rs=null;

//1、获取连接
Class.forName("com.mysql.jdbc.Driver");         
con=DriverManager.getConnection(url,username,password);

//2、创建statement
String sql="select * from test_user";
st=con.createStatement();

//3、执行sql语句并处理返回结果
rs=st.executeQuery(sql);
while(rs.next())
 {
    //对结果进行处理
  }

//4、释放资源
rs.close();
st.close();
con.close();

   以上的例子是查询的一种方法,除了用Statement外,还可以用PreparedStatement,后者是前者的子类,在前者的基础上增加了预编译和防止sql注入的功能。另外,查询和增删是不同的用法,查询会返回ResultSet而增删改不会。

2.这样写代码有什么问题

  2.1、这样的代码会造成大量重复劳动,比如获取连接,如果每个执行sql的方法都要写一遍相同的代码,那么这样的重复代码将充斥整个DAO层。

  2.2、这样的代码可读性比较差,几十行代码真正和业务相关的其实就几行

  2.3、大量重复代码会造成一个问题,那就是可维护性变差,一旦某个常量改变了。那么就需要把每个方法的该一遍,

  2.4、数据库连接是重量级资源,每调用一次方法都去创建一个连接,性能会存在瓶颈。

3、如何改进

      针对前面的问题中,改进的方法就是抽象,把可重用的代码抽象出去,单独组成一个模块,模块与模块之间实现解耦。由于整个JDBC操作流程分为4步,因此可以从这4步中下手去抽象。

     3.1、获取数据库连接

       我当时的解决方案是一次初始化很多连接放入list,然后用的时候取,现在的通用方法就是连接池,比如DBCP、C3P0等等。有兴趣的人可以去看看它们的源代码,看看是如何实现的

    3.2、创建statement

       我当时使用PreparedStatement进行处理,因为PreparedStatement会缓存已经编译过的sql

   3.3、执行sql语句并处理返回结果

     这块可以使用反射,将得到的结果封装成Java bean对象

   3.4、释放资源

     使用动态代理,改变connection的close方法的行为,将connection放回连接池

4.commons-dbutils的原理

  一共有27个类,但真正常用的是三大组件十几个类:门面组件、结果处理组件和行处理组件,其中门面组件提供程序入口,并进行一些参数检验等,结果处理组件则是核心所在,因为返回的结果可以是map,可以是list可以是JavaBean,这一块的变化很大,所以抽象出一个组件出来应对这些变化,行处理组件是从结果处理组件中分离出来的,它是结果处理组件的基础,无论哪种处理器,最终都要与一行数据打交道,因此,单独抽象出这一组件。

类名 描述
门面组件
QueryRunner 执行增删改查的入口
结果处理组件
ResultSetHandler 用于处理ResultSet的接口
AbstractKeyedHandler 将返回结果处理成键值对的抽象类
KeyedHandler

处理数据库返回结果,封装成一个Map,数据库表的一个列名为key,通常可以用主键,数据库中的一行结果以Map的形式作为value

BeanMapHandler 处理数据库返回结果,封装成一个Map,和KeyedHandler的唯一的不同是,每一行结果以Javabean的形式作为value
AbstractListHandler 将返回结果处理成链表的抽象类
ArrayListHandler

将返回结果处理成链表,这个链表的每个

元素都是一个Object数组,保存了数据库中对应的一行数据

ColumnListHandler

如果要取单独一列数据,可以用这个handler,用户指定列名,它返回这个

列的一个list

MapListHandler

和ArrayListHandler不同的是,链表的每个元素是个Map,这个Map代表数据库里的一行数据

ArrayHandler

将一行数据处理成object数组

BeanHandler

将一行数据处理成一个Java bean

BeanListHandler

将所有数据处理成一个list,list的元素时Java bean

MapHandler

将一行结果处理成一个Map

MapListHandler

将所有结果处理成一个list,list的元素时Map

ScalarHandler

这个类常常用于取单个数据,比如某一数据集的总数等等

行处理组件

RowProcessor 用于处理数据库中一行数据的接口
BasicRowProcessor 基本的行处理器实现类
BeanProcessor 通过反射将数据库数据转换成Javabean
工具类
DbUtils 包含很多JDBC工具方法

猜你喜欢

转载自www.cnblogs.com/Tony98/p/10755963.html