目录
一、简介:
commons-dbutils是Apache开源组织提供的用于操作数据库的工具包。对于数据库的操作无外乎就是【增删改查】,本质上只是SQL语法的不同。
一个普通的查询操作其处理过程如下:
- 创建Connection连接。
- 创建Statement。
- 执行SQL生成ResultSet,历遍ResultSet中的所有行记录提取列数据并转换成所需的对象。
- 释放资源。
DBUtils是在JDBC的基础上做了一层封装,解决了两个问题:
- 自动创建和释放连接资源,不再有泄漏问题。
- 自动将Result转换成对象。填入不同的ResultSetHandler,可将ResultSet转换成不同的对象。
二、主要类与相关接口介绍
DbUtils类
DbUtils主要是提供了一些加载JDBC驱动以及关闭连接的静态方法。
DbUtils.loadDriver(String driverClassName) // 加载并注册数据库驱动
DbUtils.close(Connection conn) // 关闭连接
DbUtils.close(Statement stmt)
DbUtils.close(ResultSet rs)
DbUtils.closeQuietly(Connection conn) // 关闭连接,并忽略异常
DbUtils.closeQuietly(Statement stmt)
DbUtils.closeQuietly(ResultSet rs)
DbUtils.closeQuietly(Connection conn, Statement stmt, ResultSet rs)
DbUtils.commitAndCloseQuietly(Connection conn) // 提交连接,然后关闭连接
DbUtils.rollback(Connection conn) // 回滚操作
QueryRunner类
该类简单化了 SQL 查询,它与 ResultSetHandler接口(后面将会介绍) 组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量
QueryRunner()// 构造方法
QueryRunner(DataSource ds)
query(String sql, ResultSetHandler<T> rsh) // 查询
query(String sql, ResultSetHandler<T> rsh, Object... params)
query(Connection conn, String sql, ResultSetHandler<T> rsh)
query(Connection conn, String sql, Object param, ResultSetHandler<T> rsh)
update(String sql) // 更新
update(String sql, Object... params)
update(Connection conn, String sql)
update(Connection conn, String sql, Object... params)
insert(String sql, ResultSetHandler<T> rsh, Object... params) // 插入
insert(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
batch(String sql, Object[][] params) // 批处理
batch(Connection conn, String sql, Object[][] params)
execute(String sql, Object... params) // 执行SQL语句(一般不用)
execute(String sql, ResultSetHandler<T> rsh, Object... params)
execute(Connection conn, String sql, Object... params)
execute(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
ResultSetHandler接口
这一接口执行处理一个jaca.sql.ResultSet,将数据按要求转换为另一种形式。
该接口仅提供了一个方法:T handle(ResultSet rs)
common-dbutils组件包针对这个接口提供了以下实现类:
ArrayHandler:把结果集中的第一行数据转成对象数组。
ArrayListHandler:把结果集中的每一行数据都转成一个对象数组,再存放到List中。
BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
BeanMapHandler:用于获取所有结果集,将每行结果集转换为Javabean作为value,并指定某列为key,封装到HashMap中。相当于对每行数据的做BeanHandler一样的处理后,再指定列值为Key封装到HashMap中。(1.5版本之后)
ColumnListHandler:将结果集中某一列的数据存放到List中。
KeyedHandler:将结果集中的每一行数据都封装到一个Map里,然后再根据指定的key把每个Map再存放到一个Map里。
MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
ScalarHandler:将结果集中第一条记录的其中某一列的数据存成Object
BaseResultSetHandler:如果上面的结果集处理类都不能满足你的要求,可以通过继承这个抽象类定义自己的结果处理类,子类必须实现无参方法handle()(1.6版本之后)
三、测试示例:
测试数据库:
JavaBean:
public class User { private int id; private String username; private String password; private int age;
public User() { } |
(结果出现多条的,只截取了前三条显示)
import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Properties;
import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.dbcp2.BasicDataSourceFactory; import org.apache.commons.dbutils.BaseResultSetHandler; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ArrayHandler; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.BeanMapHandler; import org.apache.commons.dbutils.handlers.ColumnListHandler; import org.apache.commons.dbutils.handlers.KeyedHandler; import org.apache.commons.dbutils.handlers.MapHandler; import org.apache.commons.dbutils.handlers.MapListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.apache.commons.lang3.ArrayUtils; import org.junit.Before; import org.junit.Test;
import com.zzs.commons.bean.User;
public class DBUtilsTest { private QueryRunner qr;
/** * 初始化 */ @Before public void init() throws Exception { Properties p = new Properties(); p.setProperty("driverClassName", "com.mysql.jdbc.Driver"); p.setProperty("url", "jdbc:mysql://localhost:3306/test"); p.setProperty("username", "root"); p.setProperty("password", "root");
BasicDataSource ds = BasicDataSourceFactory.createDataSource(p); qr = new QueryRunner(ds); }
/** * ArrayHandler测试 */ @Test public void testArrayHandler() throws SQLException { String sql = "select * from user"; Object[] objects = qr.query(sql, new ArrayHandler()); // System.out.println(ArrayUtils.toString(objects)); for (Object object : objects) { /* * 1001 zhangsan 123 22 */ System.out.print(object + "\t"); } }
/** * ArrayListHandler测试 */ @Test public void testArrayListHandler() throws SQLException { String sql = "select * from user"; List<Object[]> list = qr.query(sql, new ArrayListHandler()); for (Object[] objects : list) { /* * {1001,zhangsan,123,22} * {1002,zhangsan_2,8195,70} * {1003,zhangsan_3,3442,9} */ System.out.println(ArrayUtils.toString(objects)); } }
/** * BeanHandler测试 */ @Test public void testBeanHandler() throws SQLException { String sql = "select * from user"; // 默认的情况下要保证表的字段和javabean的属性一致(字符一致即可,对大小写不敏感) User user = qr.query(sql, new BeanHandler<User>(User.class)); /* * User [id=1001, username=zhangsan, password=123, age=22] */ System.out.println(user); }
/** * BeanListHandler测试 */ @Test public void testBeanListHandler() throws SQLException { String sql = "select * from user"; List<User> list = qr.query(sql, new BeanListHandler<>(User.class)); for (User user : list) { /* * User [id=1001, username=zhangsan, password=123, age=22] * User [id=1002, username=zhangsan_2, password=8195, age=70] * User [id=1003, username=zhangsan_3, password=3442, age=9] */ System.out.println(user); } }
/** * BeanMapHandler测试 */ @Test public void testBeanMapHandler() throws SQLException { String sql = "select * from user"; Map<Object, User> map = qr.query(sql, new BeanMapHandler<>(User.class)); // 可以指定某列作为key // Map<Object, User> map2 = qr.query(sql, new BeanMapHandler<>(User.class, "username")); for (Entry<Object, User> entry : map.entrySet()) { /* * 1008 User [id=1008, username=zhangsan_8, password=8809, age=33] * 1009 User [id=1009, username=zhangsan_9, password=7748, age=33] * 1010 User [id=1010, username=zhangsan_10, password=3338, age=18] */ System.out.println(entry.getKey() + "\t" + entry.getValue()); } }
/** * ColumnListHandler测试 */ @Test public void testColumnListHandler() throws SQLException { String sql = "select * from user"; List<Object> list = qr.query(sql, new ColumnListHandler<>()); // List<Object> list = qr.query(sql, new ColumnListHandler<>("username")); for (Object object : list) { /* * 1001 * 1002 * 1003 */ System.out.println(object); } }
/** * KeyedHandler测试 */ @Test public void testKeyedHandler() throws SQLException { String sql = "select * from user"; Map<Object, Map<String, Object>> query = qr.query(sql, new KeyedHandler<>()); // Map<Object, Map<String, Object>> query = qr.query(sql, new KeyedHandler<>("username")); for (Entry<Object, Map<String, Object>> queryEntry : query.entrySet()) { Object queryKey = queryEntry.getKey(); Map<String, Object> queryValue = queryEntry.getValue();
System.out.print(queryKey + "\t"); for (Entry<String, Object> entry : queryValue.entrySet()) { /* * 1008 id=1008 username=zhangsan_8 password=8809 age=33 * 1009 id=1009 username=zhangsan_9 password=7748 age=33 * 1010 id=1010 username=zhangsan_10 password=3338 age=18 */ System.out.print(entry.getKey() + "=" + entry.getValue() + "\t"); } System.out.println(); } }
/** * MapHandler测试 */ @Test public void testMapHandler() throws SQLException { String sql = "select * from user"; Map<String, Object> map = qr.query(sql, new MapHandler()); for (Entry<String, Object> entry : map.entrySet()) { /* * id=1001 * username=zhangsan * password=123 * age=22 */ System.out.println(entry.getKey() + "=" + entry.getValue()); } }
/** * MapListHandler测试 */ @Test public void testMapListHandler() throws SQLException { String sql = "select * from user"; List<Map<String, Object>> list = qr.query(sql, new MapListHandler()); for (Map<String, Object> map : list) { for (Entry<String, Object> entry : map.entrySet()) { /* * id=1001 username=zhangsan password=123 age=22 * id=1002 username=zhangsan_2 password=8195 age=70 * id=1003 username=zhangsan_3 password=3442 age=9 */ System.out.print(entry.getKey() + "=" + entry.getValue() + "\t"); } System.out.println(); } }
/** * ScalarHandler测试 */ @Test public void testScalarHandler() throws SQLException { String sql = "select * from user"; Object object = qr.query(sql, new ScalarHandler<>()); // Object object = qr.query(sql, new ScalarHandler<>("username")); /* * 1001 */ System.out.println(object); }
/** * BaseResultSetHandler测试 */ @Test public void testBaseResultSetHandler() throws SQLException { String sql = "select * from user"; Object object = qr.query(sql, new MyResultHandler("username")); /* * [zhangsan, zhangsan_2, zhangsan_3, zhangsan_4, zhangsan_5, zhangsan_6, * zhangsan_7, zhangsan_8, zhangsan_9, zhangsan_10] */ System.out.println(object); } }
class MyResultHandler extends BaseResultSetHandler {
private final String columnIndex;
// 指定要获取值的列 public MyResultHandler(String columnIndex) { this.columnIndex = columnIndex; }
// 重写父类的方法,封装每行数据 @Override protected List<Object> handle() throws SQLException { List<Object> rows = new ArrayList<>(); while (this.next()) { rows.add(this.getObject(this.columnIndex)); } return rows; } } |