• Java 之 JDBC:(九)Apache-DBUtils实现CRUD操作


    一、Apache-DBUtils简介

      commons-dbutils Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。

      API介绍:

        org.apache.commons.dbutils.QueryRunner
        org.apache.commons.dbutils.ResultSetHandler
        工具类:org.apache.commons.dbutils.DbUtils

      API包说明:

      

      

    二、主要 API 的使用

      1、DbUtils

        DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。主要方法如下:

    public static void close(…) throws java.sql.SQLException: DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和
    ResultSet。
    public static void closeQuietly(…): 这一类方法不仅能在Connection、Statement和ResultSet为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLEeception。
    public static void commitAndClose(Connection conn)throws SQLException: 用来提交连接的事务,然后关闭连接
    public static void commitAndCloseQuietly(Connection conn): 用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。
    public static void rollback(Connection conn)throws SQLException:允许conn为null,因为方法内部做了判断
    public static void rollbackAndClose(Connection conn)throws SQLException
    rollbackAndCloseQuietly(Connection)
    public static boolean loadDriver(java.lang.String driverClassName):这一方装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。

      

      2、QueryRunner

        该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。

        QueryRunner 类提供了两个构造器

          ① 默认的构造器;

          ② 需要一个 javax.sql.DataSource 来作参数的构造器;

        QueryRunner 类的主要方法:

          (1)更新

    public int update(Connection conn, String sql, Object... params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。
    

      

          (2)插入

    public T insert(Connection conn,String sql,ResultSetHandler rsh, Object... params) throws SQLException:
    只支持INSERT语句,其中 rsh - The handler used to create the result object fromthe ResultSet of auto-generated keys.
    返回值: An object generated by the handler.即自动生成的键值

      

          (3)批处理

    public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException: 
    INSERT,UPDATE, or DELETE语句
    public T insertBatch(Connection conn,String sql,ResultSetHandler rsh,Object[][] params)throws SQLException:
    只支持INSERT语句

      

          (4)查询

    public Object query(Connection conn, String sql, ResultSetHandler rsh,Object... params) throws SQLException:
    执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
    

      3、ResultSetHandler接口及实现类

        该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。

        ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet  rs)
        接口的主要实现类:

    ArrayHandler:把结果集中的第一行数据转成对象数组。
    
    ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
    
    BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
    
    BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
    
    ColumnListHandler:将结果集中某一列的数据存放到List中。
    
    KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
    
    MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
    
    MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
    
    ScalarHandler:查询单个值对象
    

      

    三、测试

      1、插入测试

     1     @Test
     2     public void testInsert() {
     3         Connection conn = null;
     4         try {
     5             QueryRunner runner = new QueryRunner();
     6             conn = JDBCUtils.getConnection3();
     7             String sql = "insert into customers(name,email,birth)values(?,?,?)";
     8             int insertCount = runner.update(conn, sql, "张三","zhangsan@126.com","1997-09-08");
     9             System.out.println("添加了" + insertCount + "条记录");
    10         } catch (SQLException e) {
    11             e.printStackTrace();
    12         }finally{
    13             
    14             JDBCUtils.closeResource(conn, null);
    15         }
    16     }

      2、测试查询

        (1)BeanHander 测试

     1     /*
     2      * BeanHander:是ResultSetHandler接口的实现类,用于封装表中的一条记录。
     3      */
     4     @Test
     5     public void testQuery1(){
     6         Connection conn = null;
     7         try {
     8             QueryRunner runner = new QueryRunner();
     9             conn = JDBCUtils.getConnection3();
    10             String sql = "select id,name,email,birth from customers where id = ?";
    11             BeanHandler<Customer> handler = new BeanHandler<>(Customer.class);
    12             Customer customer = runner.query(conn, sql, handler, 20);
    13             System.out.println(customer);
    14         } catch (SQLException e) {
    15             e.printStackTrace();
    16         }finally{
    17             JDBCUtils.closeResource(conn, null);
    18             
    19         }
    20         
    21     }

          运行结果:

        (2)BeanListHandler测试

     1     /*
     2      * BeanListHandler:是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合。
     3      */
     4     @Test
     5     public void testQuery2() {
     6         Connection conn = null;
     7         try {
     8             QueryRunner runner = new QueryRunner();
     9             conn = JDBCUtils.getConnection3();
    10             String sql = "select id,name,email,birth from customers where id < ?";
    11             
    12             BeanListHandler<Customer>  handler = new BeanListHandler<>(Customer.class);
    13 
    14             List<Customer> list = runner.query(conn, sql, handler, 5);
    15             list.forEach(System.out::println);
    16         } catch (SQLException e) {
    17             e.printStackTrace();
    18         }finally{
    19             
    20             JDBCUtils.closeResource(conn, null);
    21         }
    22         
    23     }

          运行结果:

        (3)MapListHandler 测试

     1     /*
     2      * MapListHander:是ResultSetHandler接口的实现类,对应表中的多条记录。
     3      * 将字段及相应字段的值作为map中的key和value。将这些map添加到List中
     4      */
     5     @Test
     6     public void testQuery4(){
     7         Connection conn = null;
     8         try {
     9             QueryRunner runner = new QueryRunner();
    10             conn = JDBCUtils.getConnection3();
    11             String sql = "select id,name,email,birth from customers where id < ?";
    12         
    13             MapListHandler handler = new MapListHandler();
    14             List<Map<String, Object>> list = runner.query(conn, sql, handler, 5);
    15             list.forEach(System.out::println);
    16         } catch (SQLException e) {
    17             e.printStackTrace();
    18         }finally{
    19             JDBCUtils.closeResource(conn, null);
    20             
    21         }
    22         
    23     }

          运行结果:

        (4)ScalarHandler 测试

     1     /*
     2      * ScalarHandler:用于查询特殊值
     3      */
     4     @Test
     5     public void testQuery5(){
     6         Connection conn = null;
     7         try {
     8             QueryRunner runner = new QueryRunner();
     9             conn = JDBCUtils.getConnection3();
    10             
    11             String sql = "select count(*) from customers";
    12             
    13             ScalarHandler handler = new ScalarHandler();
    14             
    15             Long count = (Long) runner.query(conn, sql, handler);
    16             System.out.println(count);
    17         } catch (SQLException e) {
    18             e.printStackTrace();
    19         }finally{
    20             JDBCUtils.closeResource(conn, null);
    21             
    22         }
    23         
    24     }    

        运行结果:

         测试2:

     1     @Test
     2         public void testQuery6(){
     3         Connection conn = null;
     4         try {
     5             QueryRunner runner = new QueryRunner();
     6             conn = JDBCUtils.getConnection3();
     7             
     8             String sql = "select max(birth) from customers";
     9             
    10             ScalarHandler handler = new ScalarHandler();
    11             Date maxBirth = (Date) runner.query(conn, sql, handler);
    12             System.out.println(maxBirth);
    13         } catch (SQLException e) {
    14             e.printStackTrace();
    15         }finally{
    16             JDBCUtils.closeResource(conn, null);
    17             
    18         }
    19         
    20     }

        运行结果:

      3、自定义ResultSetHandler的实现类

        ResultSetHandler 是一个对结果集处理的接口,我们可以实现此接口,然后自己处理结果集:

     1     /*
     2      * 自定义ResultSetHandler的实现类
     3      */
     4     @Test
     5     public void testQuery7(){
     6         Connection conn = null;
     7         try {
     8             QueryRunner runner = new QueryRunner();
     9             conn = JDBCUtils.getConnection3();
    10             
    11             String sql = "select id,name,email,birth from customers where id = ?";
    12             ResultSetHandler<Customer> handler = new ResultSetHandler<Customer>(){
    13 
    14                 @Override
    15                 public Customer handle(ResultSet rs) throws SQLException {
    16 //                    System.out.println("handle");
    17 //                    return null;
    18                     
    19 //                    return new Customer(12, "成龙", "Jacky@126.com", new Date(234324234324L));
    20                     
    21                     if(rs.next()){
    22                         int id = rs.getInt("id");
    23                         String name = rs.getString("name");
    24                         String email = rs.getString("email");
    25                         Date birth = rs.getDate("birth");
    26                         Customer customer = new Customer(id, name, email, birth);
    27                         return customer;
    28                     }
    29                     return null;
    30                     
    31                 }
    32                 
    33             };
    34             Customer customer = runner.query(conn, sql, handler,5);
    35             System.out.println(customer);
    36         } catch (SQLException e) {
    37             e.printStackTrace();
    38         }finally{
    39             JDBCUtils.closeResource(conn, null);
    40             
    41         }
    42         
    43     }

      4、资源的关闭

          使用dbutils.jar中提供的DbUtils工具类,实现资源的关闭

          方式一:

     1     public static void closeResource1(Connection conn,Statement ps,ResultSet rs){
     2         try {
     3             DbUtils.close(conn);
     4         } catch (SQLException e) {
     5             e.printStackTrace();
     6         }
     7         try {
     8             DbUtils.close(ps);
     9         } catch (SQLException e) {
    10             e.printStackTrace();
    11         }
    12         try {
    13             DbUtils.close(rs);
    14         } catch (SQLException e) {
    15             e.printStackTrace();
    16         }
    17     }

          DBUtils 里面对这些做了非空判断:

          方式二:

    1   public static void closeResource1(Connection conn,Statement ps,ResultSet rs){
    2         DbUtils.closeQuietly(conn);
    3         DbUtils.closeQuietly(ps);
    4         DbUtils.closeQuietly(rs);
    5     }

        closeQuietly 方法中进行了异常的捕获。

  • 相关阅读:
    ruby 二进制转十进制 Integer("0b101") = 5
    开始菜单和我的文档的我的图片及我的音乐变成 my pictrues 正常图标了
    ruby watir 莫名其妙的错误
    Excel SaveAS是去掉提示框
    apache && jboss安装
    ruby require include的区别
    ruby控制鼠标
    This error is raised because the column 'type' is reserved for storing the class in case of inheritance
    用正则表达式限制文本框只能输入数字,小数点,英文字母,汉字等各类代码
    ASP.NET 如何动态修改 Header 属性如添加 Meta 标签 keywords description!
  • 原文地址:https://www.cnblogs.com/niujifei/p/15026442.html
Copyright © 2020-2023  润新知