简介
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连接池的配置可以看这里 十二、数据库连接池