Apache—dbutils开源JDBC工具类库简介

Apache—dbutils开源JDBC工具类库简介

一、前言

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

  API介绍:
  ①org.apache.commons.dbutils.QueryRunner
  ②org.apache.commons.dbutils.ResultSetHandler

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

二、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 commitAndCloseQuietly(Connection conn):
  用来提交连接,然后关闭连接,并且在关闭连接时不抛出SQL异常。

  ④public static boolean loadDriver(java.lang.String driverClassName):

  这一方装载并注册JDBC驱动程序,如果成功就返回true。使用该方法,你不需要捕捉这个异常ClassNotFoundException。

三、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:

  用来执行一个更新(插入、更新或删除)操作。

四、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

五、代码示例

  1 package me.jdbc.day04;
  2 
  3 import java.io.IOException;
  4 import java.sql.Connection;
  5 import java.sql.Date;
  6 import java.sql.ResultSet;
  7 import java.sql.SQLException;
  8 import java.util.ArrayList;
  9 import java.util.List;
 10 import java.util.Map;
 11 
 12 import org.apache.commons.dbutils.QueryLoader;
 13 import org.apache.commons.dbutils.QueryRunner;
 14 import org.apache.commons.dbutils.ResultSetHandler;
 15 import org.apache.commons.dbutils.handlers.BeanListHandler;
 16 import org.apache.commons.dbutils.handlers.MapHandler;
 17 import org.apache.commons.dbutils.handlers.MapListHandler;
 18 import org.apache.commons.dbutils.handlers.ScalarHandler;
 19 import org.junit.Test;
 20 
 21 import me.jdbc.day02.Customer;
 22 
 23 /**
 24  * Apache DBUtils测试类
 25  * 
 26  * @author Administrator
 27  *
 28  */
 29 public class DBUtilsTest {
 30 
 31     /**
 32      * QueryLoader: 可以用来加载存放着 SQL 语句的资源文件. 使用该类可以把 SQL 语句外置化到一个资源文件中. 以提供更好的解耦
 33      * 
 34      * @throws IOException
 35      */
 36     @Test
 37     public void testQueryLoader() throws IOException {
 38     // / 代表类路径的根目录.
 39     Map<String, String> sqls = QueryLoader.instance().load("/sql.properties");
 40 
 41     String updateSql = sqls.get("UPDATE_CUSTOMER");
 42     System.out.println(updateSql);
 43     }
 44 
 45     /**
 46      * 1. ResultSetHandler 的作用: 
 47      * QueryRunner 的 query 方法的返回值最终取决于 query 方法的ResultHandler 参数的 hanlde 方法的返回值.
 48      * 
 49      * 2. BeanListHandler: 把结果集转为一个 Bean 的 List, 并返回. 
 50      * Bean 的类型在 创建BeanListHanlder 对象时以 Class 对象的方式传入. 
 51      * 可以适应列的别名来映射 JavaBean 的属性名: 
 52      * String sql = "SELECT id, name customerName, email, birth FROM customers WHERE id = ?";
 53      * 
 54      * BeanListHandler(Class<T> type)
 55      * 
 56      * 3. BeanHandler: 把结果集转为一个 Bean, 并返回. 
 57      * Bean 的类型在创建 BeanHandler 对象时以 Class对象的方式传入 BeanHandler(Class<T> type)
 58      * 
 59      * 4. MapHandler: 把结果集转为一个 Map 对象, 并返回. 若结果集中有多条记录, 仅返回 第一条记录对应的 Map 对象. 
 60      * Map的键: 列名(而非列的别名), 值: 列的值
 61      * 
 62      * 5. MapListHandler: 把结果集转为一个 Map 对象的集合, 并返回. Map 的键: 列名(而非列的别名), 值: 列的值
 63      * 
 64      * 6. ScalarHandler: 可以返回指定列的一个值或返回一个统计函数的值.
 65      */
 66 
 67     @Test
 68     public void testScalarHandler() {
 69     Connection connection = null;
 70     QueryRunner queryRunner = new QueryRunner();
 71 
 72     String sql = "SELECT name FROM customers WHERE id = ?";
 73 
 74     try {
 75         connection = JDBCTools.getConnection();
 76         Object count = queryRunner.query(connection, sql, new ScalarHandler(), 6);
 77 
 78         System.out.println(count);
 79     } catch (Exception e) {
 80         e.printStackTrace();
 81     } finally {
 82         JDBCTools.releaseDB(null, null, connection);
 83     }
 84     }
 85 
 86     @Test
 87     public void testMapListHandler() {
 88     Connection connection = null;
 89     QueryRunner queryRunner = new QueryRunner();
 90 
 91     String sql = "SELECT id, name, email, birth FROM customers";
 92 
 93     try {
 94         connection = JDBCTools.getConnection();
 95         List<Map<String, Object>> mapList = queryRunner.query(connection, sql, new MapListHandler());
 96 
 97         System.out.println(mapList);
 98     } catch (Exception e) {
 99         e.printStackTrace();
100     } finally {
101         JDBCTools.releaseDB(null, null, connection);
102     }
103     }
104 
105     @Test
106     public void testMapHandler() {
107     Connection connection = null;
108     QueryRunner queryRunner = new QueryRunner();
109 
110     String sql = "SELECT id, name customerName, email, birth FROM customers WHERE id = ?";
111 
112     try {
113         connection = JDBCTools.getConnection();
114         Map<String, Object> map = queryRunner.query(connection, sql, new MapHandler(), 4);
115 
116         System.out.println(map);
117     } catch (Exception e) {
118         e.printStackTrace();
119     } finally {
120         JDBCTools.releaseDB(null, null, connection);
121     }
122     }
123 
124     /**
125      * 测试 ResultSetHandler 的 BeanListHandler 
126      * 实现类 BeanListHandler: 把结果集转为一个 Bean的 List. 
127      * 该 Bean 的类型在创建 BeanListHandler 对象时传入:
128      * new BeanListHandler<>(Customer.class)
129      * 
130      */
131     @Test
132     public void testBeanListHandler() {
133     String sql = "SELECT id, name, email, birth FROM customers";
134 
135     // 1. 创建 QueryRunner 对象
136     QueryRunner queryRunner = new QueryRunner();
137 
138     Connection conn = null;
139 
140     try {
141         conn = JDBCTools.getConnection();
142 
143         Object object = queryRunner.query(conn, sql, new BeanListHandler<>(Customer.class));
144 
145         System.out.println(object);
146     } catch (Exception e) {
147         e.printStackTrace();
148     } finally {
149         JDBCTools.releaseDB(null, null, conn);
150     }
151     }
152 
153     /**
154      * 测试 QueryRunner 的 query 方法
155      */
156     @SuppressWarnings({ "unchecked", "rawtypes" })
157     @Test
158     public void testResultSetHandler() {
159     String sql = "SELECT id, name, email, birth FROM customers";
160 
161     // 1. 创建 QueryRunner 对象
162     QueryRunner queryRunner = new QueryRunner();
163 
164     Connection conn = null;
165 
166     try {
167         conn = JDBCTools.getConnection();
168         /**
169          * 2. 调用 query 方法: ResultSetHandler 
170          * 参数的作用: query 方法的返回值直接取决于ResultSetHandler 的 hanlde(ResultSet rs) 是如何实现的. 
171          * 实际上, 在QueryRunner 类的 query 方法中也是调用了 ResultSetHandler 的 handle()方法作为返回值的。
172          */
173         Object object = queryRunner.query(conn, sql, new ResultSetHandler() {
174         @Override
175         public Object handle(ResultSet rs) throws SQLException {
176             List<Customer> customers = new ArrayList<>();
177 
178             while (rs.next()) {
179             int id = rs.getInt(1);
180             String name = rs.getString(2);
181             String email = rs.getString(3);
182             Date birth = rs.getDate(4);
183 
184             Customer customer = new Customer(id, name, email, birth);
185             customers.add(customer);
186             }
187 
188             return customers;
189         }
190         });
191 
192         System.out.println(object);
193     } catch (Exception e) {
194         e.printStackTrace();
195     } finally {
196         JDBCTools.releaseDB(null, null, conn);
197     }
198 
199     }
200 
201     /**
202      * 测试 QueryRunner 类的 update 方法 
203      * 该方法可用于 INSERT, UPDATE 和 DELETE
204      */
205     @Test
206     public void testQueryRunnerUpdate() {
207     // 1. 创建 QueryRunner 的实现类
208     QueryRunner queryRunner = new QueryRunner();
209 
210     String sql = "DELETE FROM customers WHERE id IN (?,?)";
211 
212     Connection connection = null;
213 
214     try {
215         connection = JDBCTools.getConnection();
216         // 2. 使用其 update 方法
217         queryRunner.update(connection, sql, 12, 13);
218     } catch (Exception e) {
219         e.printStackTrace();
220     } finally {
221         JDBCTools.releaseDB(null, null, connection);
222     }
223 
224     }
225 
226 }
View Code

如果,您对我的这篇博文有什么疑问,欢迎评论区留言,大家互相讨论学习。
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博文感兴趣,可以关注我的后续博客,我是【AlbertRui】。

转载请注明出处和链接地址,欢迎转载,谢谢!

原文地址:https://www.cnblogs.com/albertrui/p/8424519.html