简介
commons-dbutils 是
Apache
组织提供的一个开源
JDBC
工具类库,它是对
JDBC
的简单封装,学习成本极低,并且使用
dbutils
能极大简化
jdbc
编码的工作量,同时也不会影响程序的性能。因此
dbutils
成为很多不喜欢
hibernate
的公司的首选。
DbUtils的核心API
DbUtils 简化了数据库的CRUD的操作
、提供了如关闭连接,装载驱动程序等常规操作的工具类,核心API有3个,

QueryRunner类、
ResultSetHandler接口、
DbUtils工具类,源码结构如下:

QueryRunner类
简化了SQL的CRUD操作(与ResultSetHandler接口组合可以完成大部分的数据查询操作,能够大大减少编码量)
构造函数:
QueryRunner() (手动管理事务)
QueryRunner(DataSource ds)(自动管理事务)
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:用来执行一个不需要置换参数的更新操作。
DbUtils类
提供如关闭连接、装载
JDBC
驱动程序等常规工作的工具类,里面的所有方法都是静态的。
该类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭Connection、Statement和ResultSet。
主要方法:
public static void close(…
) throws java.sql.SQLException
:
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
。
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
ScalarHandler: 用于做单值查询的情况
.
查询有效数据的个数。
当然如果上面的都觉得不够用,你完全可以自行实现ResultSetHandler 接口进行处理。
下面通过demo来演示dbutils的使用。
项目工程如下:
测试的数据库结构如下:
demo1
package demo1;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Demo1 {
private QueryRunner qrunner = new QueryRunner(new ComboPooledDataSource());
/**
* 使用dbutils的增、删、改的方法
*
* @throws Exception
*/
@Test
public void testUpdate() throws Exception {
// 测试insert
qrunner.update("insert into account values(null,'zs',200);");
// 测试delete
qrunner.update("delete from account where name = ?", "a");
// 测试update
qrunner.update("update account set money = ? where name = ?", 1000, "b");
}
}
demo2
package demo2;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import bean.Account;
public class Demo2 {
private QueryRunner qrunner = new QueryRunner(new ComboPooledDataSource());
/**
* 测试用BeanListHandler处理查询结果,返回一个集合bean
*
* @throws Exception
*/
@Test
public void testBeanListHandler() throws Exception {
List<Account> list = qrunner.query("select * from account where money > ?",
new BeanListHandler<Account>(Account.class), 100);
for (Account account : list) {
System.out.println(account);
}
}
/**
* 测试用ColumnListHandler处理查询结果,返回某一列的所有值
*
* @throws Exception
*/
@Test
public void testColumnListHandler() throws Exception {
/*
* List<Object> list = qrunner.query("select * from account where money > ?",
* new ColumnListHandler("name"), 100);
*/
List<Object> list = qrunner.query("select * from account", new ColumnListHandler("name"));
for (Object value : list) {
System.out.println(value);
}
}
/**
* 测试用ScalarHandler处理聚合函数的查询结果
*
* @throws Exception
*/
@Test
public void testScalarHandler() throws Exception {
Long count = (Long) qrunner.query("select count(*) from account", new ScalarHandler());
System.out.println(count);
}
/**
* 测试用MapListHandler处理查询结果
*
* @throws Exception
*/
@Test
public void testMapListHandler() throws Exception {
List<Map<String, Object>> list = qrunner.query("select * from account", new MapListHandler());
for (Map<String, Object> map : list) {
for (String key : map.keySet()) {
System.out.println("key:" + key + " values:" + map.get(key));
}
}
}
}
account
package bean;
/**
* 和数据库对应的实体,必须要有set方法,因为dbutils是通过set方法来设置字段的
*
* @author mChenys
*
*/
public class Account {
public int id;
public String name;
public double money;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
}
}
关于c3p0连接池的配置可以看这里
十二、数据库连接池