Apache的DBUtils

转自: http://blog.csdn.net/yerenyuan_pku/article/details/52372703

commons-dbutils简介

commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。
commons-dbutils API介绍:

  • org.apache.commons.dbutils.QueryRunner QueryRunner中有update()和query()方法
  • org.apache.commons.dbutils.ResultSetHandler

工具类:

  • org.apache.commons.dbutils.DbUtils

QueryRunner类使用讲解

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

  • 默认的构造方法。
  • 需要一个javax.sql.DataSource来作参数的构造方法。

QueryRunner类的主要方法

  • public Object query(Connection conn, String sql, Object[] params, ResultSetHandler rsh) throws SQLException
    执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句的置换参数。该方法会自行处理PreparedStatement和ResultSet的创建和关闭。
  • public Object query(String sql, Object[] params, ResultSetHandler rsh) throws SQLException
    几乎与第一种方法一样;唯一的不同在于它不将数据库连接提供给方法,并且它是从提供给构造方法的数据源(DataSource)或使用的setDataSource方法中重新获得Connection。
  • public Object query(Connection conn, String sql, ResultSetHandler rsh) throws SQLException
    执行一个不需要置换参数的查询操作。
  • public int update(Connection conn, String sql, Object[] params) throws SQLException
    用来执行一个更新(插入、更新或删除)操作。
  • public int update(Connection conn, String sql) throws SQLException
    用来执行一个不需要置换参数的更新操作。
  • public int[] batch(Connection conn, String sql, Object[][] params) throws SQLException
    这个方法对应着批处理,经常用于在同一个表中批量插入数据,或批量更新表的数据。
    该方法为何会接收二维数组Object[][] params呢?
    答:例如现在要想在同一个表中批量插入数据,编写的SQL语句为:

    String sql = "insert into users(id,name) values(?,?)";
         
         
    • 1

    该方法接收二维数组Object[][] params,那么调用其的时候就要传递一个诸如这样的实参[[1,aa],[2,bb],[3,cc]],即用二维数组里面的每一个一维数组生成一条sql语句。
    那为何又会返回int[]呢?
    答:该方法的返回值是int[],所以会返回诸如这样的结果:[1,1,1],意思是生成的第一条sql语句影响数据库几行、生成的第二条sql语句影响数据库几行、生成的第三条sql语句影响数据库几行。

ResultSetHandler接口使用讲解

该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。ResultSetHandler接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)

ResultSetHandler接口的实现类

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

DbUtils类使用讲解

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

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

使用DBUtils完成数据库的CRUD

在使用DBUtils完成数据库的CRUD之前,我们先编写测试用的SQL脚本:

create database day17;
use day17;
create table users 
(
    id int primary key,
    name varchar(40),
    password varchar(40),
    email varchar(60),
    birthday date
);
   
   

    在应用程序中加入dbcp连接池

    导入相关jar包:

    • commons-dbcp-1.4.jar
    • commons-pool-1.6.jar

    在类目录下加入dbcp的配置文件:dbcpconfig.properties。dbcpconfig.properties的配置信息如下:

    #连接设置
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/day17
    username=root
    password=yezi
    
    
    
    
    
    
    # <!– 初始化连接 –> initialSize=10 #最大连接数量 maxActive=50 # <!– 最大空闲连接 –> maxIdle=20 # <!– 最小空闲连接 –> minIdle=5 # <!– 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 –> maxWait=60000 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:”user” 与 “password” 两个属性会被明确地传递,因此这里不需要包含他们。 connectionProperties=useUnicode=true;characterEncoding=utf8 #指定由连接池所创建的连接的自动提交(auto-commit)状态。 defaultAutoCommit=true #driver default 指定由连接池所创建的连接的只读(read-only)状态。 #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix) defaultReadOnly= #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。 #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=READ_COMMITTED

      如下图所示:
      这里写图片描述

      使用QueryRunner类实现CRUD

      在cn.itcast.domain包下创建一个封装数据的实体——User.java,对应数据库中的users表。User类的具体代码如下:

      public class User {
          private int id;
          private String name;
          private String password;
          private String email;
          private Date birthday;
          public int getId() {
              return id;
          }
          public void setId(int id) {
              this.id = id;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public String getPassword() {
              return password;
          }
          public void setPassword(String password) {
              this.password = password;
          }
          public String getEmail() {
              return email;
          }
          public void setEmail(String email) {
              this.email = email;
          }
          public Date getBirthday() {
              return birthday;
          }
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
      }
       
       

        在cn.itcast.utils包下创建一个获取数据库连接的工具类(JdbcUtils),该工具类(JdbcUtils)的代码为:

        public class JdbcUtils {
            private static DataSource ds = null;
        
            static {
                try {
                    Properties prop = new Properties();
                    InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
                    prop.load(in);
                    BasicDataSourceFactory factory = new BasicDataSourceFactory();
                    ds = factory.createDataSource(prop);
                } catch (Exception e) {
                    throw new ExceptionInInitializerError(e);
                }
            }
        
            public static DataSource getDataSource() {
                return ds;
            }
        
            public static Connection getConnection() throws SQLException {
                return ds.getConnection();
            }
        
            /*
             * 工具类里面现在没有必要提供release()方法,因为我们是使用dbutils操作数据库,
             * 即调用dbutils的update()和query()方法操作数据库,他操作完数据库之后,会自动释放掉连接。
             */
        }
         
         

          提示:工具类里面现在没有必要提供release()方法,因为我们是使用DBUtils操作数据库,即调用DBUtils的update()和query()方法操作数据库,它操作完数据库之后,会自动释放掉连接。
          现在在cn.itcast.dbutils.demo包下新建一个测试类Demo1.java,Demo1类的具体代码如下:

          public class Demo1 {    
              // 使用dbutils完成数据库的CRUD
              @Test
              public void insert() throws SQLException {
                  QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                  String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
                  Object[] params = {2, "bbb", "123", "bbb@163.com", new Date()};
                  runner.update(sql, params);
              }
          
              @Test
              public void update() throws SQLException {
                  QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                  String sql = "update users set email=? where id=?";
                  Object[] params = {"yeyiyi@126.com", 1};
                  runner.update(sql, params);
              }
          
              @Test
              public void delete() throws SQLException {
                  QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                  String sql = "delete from users where id=?";
                  runner.update(sql, 2);
              }
          
              @Test
              public void find() throws SQLException {
                  QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                  String sql = "select * from users where id=?";
                  User user = (User) runner.query(sql, 1, new BeanHandler(User.class));
                  System.out.println(user.getEmail());
              }
          
              @Test
              public void getAll() throws SQLException {
                  QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                  String sql = "select * from users";
                  List list = (List) runner.query(sql, new BeanListHandler(User.class));
                  System.out.println(list);
              }
          
              @Test
              public void batch() throws SQLException {
                  QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                  String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
                  Object[][] params = new Object[3][5];
                  for (int i = 0; i < params.length; i++) {
                      params[i] = new Object[]{i+1, "aa"+i, "123", i+"@sian.com", new Date()};
                  }
                  runner.batch(sql, params);
              }
          }
           
           

            测试dbutils各种类型的处理器

            在使用DBUtils完成数据库的CRUD中,我们就已经测试过BeanHandler和BeanListHandler处理器,现在我们来一个个测试其余的处理器。

            • ArrayHandler:把结果集中的第一行数据转成对象数组。测试代码如下:

              // 测试dbutils的各个结果集处理器
              public class Demo2 {
                  @Test
                  public void test1() throws SQLException {
                      QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                      String sql = "select * from users";
                      Object[] result = runner.query(sql, new ArrayHandler());
                      System.out.println(result[0]);
                      System.out.println(result[1]);
                  }
              }
                 
                 
              • ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。测试代码如下:

                // 测试dbutils的各个结果集处理器
                public class Demo2 {
                    @Test
                    public void test2() throws SQLException {
                        QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                        String sql = "select * from users";
                        List list = runner.query(sql, new ArrayListHandler());
                        System.out.println(list);
                    }
                }
                   
                   
                • ColumnListHandler:将结果集中某一列的数据存放到List中。测试代码如下:

                  // 测试dbutils的各个结果集处理器
                  public class Demo2 {
                      @Test
                      public void test3() throws SQLException {
                          QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                          String sql = "select * from users";
                          List list = (List) runner.query(sql, new ColumnListHandler("name"));
                          System.out.println(list);
                      }
                  }
                     
                     

                    我们也可以自己重新写出这样一个ColumnListHandler处理器,如:

                    class ColumnListHandler1 implements ResultSetHandler {
                    
                        private String columnName;
                    
                        public ColumnListHandler1(String columnName) {
                            this.columnName = columnName;
                        }
                    
                        @Override
                        public Object handle(ResultSet rs) throws SQLException {
                            List list = new ArrayList();
                            while (rs.next()) {
                                list.add(rs.getObject(columnName));
                            }
                            return list;
                        }
                    
                    }
                       
                       

                      用我们自己编写的ColumnListHandler1处理器来测试,代码为:

                      // 测试dbutils的各个结果集处理器
                      public class Demo2 {
                          @Test
                          public void test3() throws SQLException {
                              QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                              String sql = "select * from users";
                              List list = (List) runner.query(sql, new ColumnListHandler1("name"));
                              System.out.println(list);
                          }
                      }
                         
                         
                      • KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
                        这话听起来有些绕口,但我用一张图来解释就很明白了。
                        这里写图片描述
                        明白原理之后,就很容易写测试代码了,测试代码为:

                        // 测试dbutils的各个结果集处理器
                        public class Demo2 {
                            @Test
                            public void test4() throws SQLException {
                                QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                                String sql = "select * from users";
                                Map<Integer, Map<String, Object>> map = (Map<Integer, Map<String, Object>>) runner.query(sql, new KeyedHandler("id"));
                                for (Map.Entry<Integer, Map<String, Object>> me : map.entrySet()) {
                                    int id = me.getKey();
                                    for (Map.Entry<String, Object> entry : me.getValue().entrySet()) {
                                        String name = entry.getKey();
                                        Object value = entry.getValue();
                                        System.out.println(name+"="+value);
                                    }
                                }
                            }
                        }
                           
                           
                        • 当想要查询某张表中的总记录数时,我们可以用ArrayHandler处理器来处理。作为一个新手,第一次写代码时,可能会这样写:

                          // 测试dbutils的各个结果集处理器
                          public class Demo2 {
                              @Test
                              public void test5() throws SQLException {
                                  QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                                  String sql = "select count(*) from users";
                                  Object[] result = runner.query(sql, new ArrayHandler());
                                  int totalrecord = (int) result[0];
                                  System.out.println(totalrecord);
                              }
                          }
                             
                             

                            JUnit测试可发现报如下异常:

                            java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
                               
                               
                            • 1

                            原因是:查询结果——总记录数是作为java.lang.Long类型返回的。所以我们应该把代码修改为:

                            // 测试dbutils的各个结果集处理器
                            public class Demo2 {
                                @Test
                                public void test5() throws SQLException {
                                    QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                                    String sql = "select count(*) from users";
                                    Object[] result = runner.query(sql, new ArrayHandler());
                                    long totalrecord = (Long) result[0]; // 查询结果——总记录数是作为java.lang.Long类型返回的
                                    int num = (int) totalrecord;
                                    System.out.println(num);
                                }
                            }
                               
                               

                              除此之外,我们又可写为:

                              // 测试dbutils的各个结果集处理器
                              public class Demo2 {
                                  @Test
                                  public void test5() throws SQLException {
                                      QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                                      String sql = "select count(*) from users";
                                      Object[] result = runner.query(sql, new ArrayHandler());
                                      int totalrecord =  ((Long) result[0]).intValue();
                                      System.out.println(totalrecord);
                                  }
                              }
                                 
                                 

                                更加专业一点的方法是使用ScalarHandler处理器,测试代码如下:

                                // 测试dbutils的各个结果集处理器
                                public class Demo2 {
                                    @Test
                                    public void test5() throws SQLException {
                                        QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
                                        String sql = "select count(*) from users";
                                        int totalrecord = ((Long)runner.query(sql, new ScalarHandler(1))).intValue();
                                        System.out.println(totalrecord);
                                    }
                                }
                                   
                                   
                                • 0
                                  点赞
                                • 1
                                  收藏
                                  觉得还不错? 一键收藏
                                • 0
                                  评论
                                commons-dbutils包是Apache开源组织提供的用于操作数据库的工具包。简单来讲,这个工具包就是用来更加方便我们操作数据库的,最近工作中使用了一下,感觉确实方便很多,基本告别自己封装JDBC代码对数据库进行增删改查了。代码看着也很简洁。 例如: 增删改查使用的类:QueryRunner类+ResultSetHandler类,使用这俩类就可以解决掉。 QueryRunner类的query()方法:new QueryRunner().query(Connection conn, String sql, ResultSetHandler rsh) query方法后面参数中加一个Connection连接,是在获取不到数据源的情况下,也就是说,QueryRunner的实例化构造函数使用无参的那个,下面我的实现代码就是用的这种方法。 当然还有一种实例化:new QueryRunner(new Datasource()).query(String sql, ResultSetHandler rsh) query方法中的参数 ResultSetHandler 参数中加上ResultSetHandler接口的实现类参数(下面这些实现类),执行完SQL后,返回的数据就是已经封装好的我们想要的结果了。 ArrayHandler :将ResultSet中第一行的数据转化成对象数组 ArrayListHandler将ResultSet中所有的数据转化成List,List中存放的是Object[] BeanHandler :将ResultSet中第一行的数据转化成Bean对象 BeanListHandler :将ResultSet中所有的数据转化成List ColumnListHandler :将ResultSet中某一列的数据存成List KeyedHandler :将ResultSet中存成映射,key为某一列对应为Map,Map中存放的是数据 MapHandler :将ResultSet中第一行的数据存成Map MapListHandler :将ResultSet中所有的数据存成List<Map> ScalarHandler :将ResultSet中一条记录的其中某一列的数据存成Object

                                “相关推荐”对你有帮助么?

                                • 非常没帮助
                                • 没帮助
                                • 一般
                                • 有帮助
                                • 非常有帮助
                                提交
                                评论
                                添加红包

                                请填写红包祝福语或标题

                                红包个数最小为10个

                                红包金额最低5元

                                当前余额3.43前往充值 >
                                需支付:10.00
                                成就一亿技术人!
                                领取后你会自动成为博主和红包主的粉丝 规则
                                hope_wisdom
                                发出的红包
                                实付
                                使用余额支付
                                点击重新获取
                                扫码支付
                                钱包余额 0

                                抵扣说明:

                                1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                                2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                                余额充值