一、DButils
commons-dbutils是阿帕奇(Apache)提供的一个开源的JDBC工具类库,它将JDBC进行了一系列简单的封装,使用起来很方便,并且其源代码极易读懂,因此,使用dbutils能够从很大程度上减少JDBC编码的工作量。我们可以从Apache官网去下载到这个工具包,下载地址为 http://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi
如果想要对数据库进行操作的话,可以使用dbutils中包含一些类,这些类中包含了用于对数据库执行更新操作与执行查询操作等方法。下面详细介绍一下
二、DButils类
该类中提供了一些用于关闭连接,加载JDBC驱动程序等工具类,里面所有的方法都为静态的,主要方法有如下几种:
1、public static void close(...) 该类方法有三个重载方法用于关闭Connection、Statement、ResultSet,如果他们不为null就关闭他们。
2、public static void closeQuietly(...) 该类方法有四个重载方法,除了能够在Connection、Statement、ResultSet为null的情况下避免关闭之外,还隐藏了一些程序中可能抛出的异常(原理就是捕获了异常,但是不对其进行任何的处理)
3、public static void commitAndCloseQuietly()(Connection con) 用来提交和关闭连接,并且隐藏了一些异常
4、public static boolean loadDriver(String driverClassName) 该类方法用于装载JDBC驱动程序,如果成功,就返回true,并且使用该方法不用捕捉ClassNotFoundException
三、QueryRunner类
该类将JDBC查询及更新的步骤进行了包装,从而简化了操作,他和ResultSetHandler一起使用可以完成大部分的数据库操作,其提供了两个构造方法:
1、默认的无参构造方法
2、需要传入一个DataSource类对象来作为参数的构造方法
其主要方法如下:
1、public Object query(Connection con ,String sql,ResuleSetHandler rsh,
Object[] params ) 执行一个查询操作,该查询中,对象数组中的每个元素值被用来替换"?"参数,并且该方法还会创建和关闭PreparedStatement和ResultSet
2、pubilc Object query(String sql,ResuleSetHandler rsh,Object[] params ) 和上一个方法差不多,只是它连接数据库时使用的是从提供给构造方法的数据源(DataSource)中获得Connection
3、public Object query(Connection con ,String sql,ResuleSetHandler rsh ) 执行一个不需要填充占位符"?"的查询操作
4、public int update(Connection con,String sql,Object[] params ) 用来执行一个更新操作
5、public int update(Connection con,String sql ) 执行一个不需要填充占位符"?"的更新操作
四、ResultSetHandler接口及其实现类
ResultSetHandler接口及其实现类是用来处理ResultSet结果集的工具,其中ResultSetHandler接口中提供了一个方法为:Object
handle(ResultSet rs)。
ResultSetHandler接口的实现类有很多种,我们可以根据自己的需要来选择使用哪一种,下面来详细介绍一下其实现类:
1、ArrayHandler: 将查询所得结果集中的第一行数据转为对象数组
2、ArrayListHandler: 将结果集中的每一行都转换成一个数组,存放在List集合中
3、BeanHandler: 将结果集中的第一行数据封装到一个对应的JavaBean实例中
4、BeanListHandler: 将结果集中的每一行数据都封装到一个对应的JavaBean实例中,并存放在List集合中
5、ColumnListHandler: 将结果集中的某一列的数据存放在List集合中
6、MapHandler: 将结果集中的第一行数据封装到一个Map集合中,key是列名(不是别名),value为其对应的值
7、MapListHandler: 将结果集中的每一行数据都封装到一个Map集合中,然后再存放到List中
8、ScalarHandler: 可以返回指定列的第一行的一个值
如果你没有找到你想要用的方法,就自己实现ResultSetHandler中的handle方法把,你可以指定自己想要的返回结果,因为query()方法的返回值取决于ResultSetHandler接口中的handle方法是如何实现的
下面是一个实例用来测试这些方法:
现在本地数据库中有这样一个表:
要对该数据库执行查询和更新操作,代码如下
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
/**
* DButils工具的使用
* @author wushijia
*
*/
public class Test_dbutils {
/**
* 使用DButils进行数据库的更新操作
*/
@Test
public void test1(){
Connection con = null;
//1、创建QueryRunner的对象实例
QueryRunner queryRunner = new QueryRunner();
String sql = "INSERT INTO customer(id,name,date) VALUES(?,?,?)";
try {
con = JDBCTools.getConnection();
//2、调用其update方法
queryRunner.update(con, sql, 2,"Jerry",new Date(new java.util.Date().getTime()));
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(null, null, con);
}
}
/**
* 自己实现handle方法来测试query
*/
@Test
public void testResultSetHandle(){
Connection con = null;
QueryRunner queryRunner = new QueryRunner();
String sql = "SELECT id,name,date FROM customer";
try {
con = JDBCTools.getConnection();
Object object = queryRunner.query(con, sql, new ResultSetHandler(){
@Override
public Object handle(ResultSet rs) throws SQLException {//自己实现handle方法
List customers = new ArrayList<>();
while(rs.next()){
int id = rs.getInt(1);
String name = rs.getString(2);
Date date = rs.getDate(3);
Customer customer = new Customer(id,name,date);
customers.add(customer);
}
return customers;
}
});
System.out.println(object);//[Customer [id=1, name=Tom, date=2017-07-15], Customer [id=2, name=Jerry, date=2017-07-15]]
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(null, null, con);
}
}
/**
* 测试ResultSetHandle接口的实现类BeanListHandler
*/
@Test
public void testBeanListHandler(){
Connection con = null;
QueryRunner queryRunner = new QueryRunner();
String sql = "SELECT I_D id,name,date FROM customer";
try {
con = JDBCTools.getConnection();
Object object = queryRunner.query(con, sql, new BeanListHandler(Customer.class));
System.out.println(object);//[Customer [id=1, name=Tom, date=2017-07-15], Customer [id=2, name=Jerry, date=2017-07-15]]
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(null, null, con);
}
}
/**
* 测试ResultSetHandle接口的实现类BeanHandler
*/
@Test
public void testBeanHandler(){
Connection con = null;
QueryRunner queryRunner = new QueryRunner();
String sql = "SELECT I_D id,name,date FROM customer";
try {
con = JDBCTools.getConnection();
Object object = queryRunner.query(con, sql, new BeanHandler<>(Customer.class));
System.out.println(object);//Customer [id=1, name=Tom, date=2017-07-15]
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(null, null, con);
}
}
/**
* 测试ResultSetHandle接口的实现类MapListHandler
*/
@Test
public void testMapListHandler(){
Connection con = null;
QueryRunner queryRunner = new QueryRunner();
String sql = "SELECT I_D id,name,date FROM customer";
try {
con = JDBCTools.getConnection();
List> object = queryRunner.query(con, sql, new MapListHandler());
System.out.println(object);//[{id=1, name=Tom, date=2017-07-15}, {id=2, name=Jerry, date=2017-07-15}]
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(null, null, con);
}
}
/**
* 测试ResultSetHandle接口的实现类ScalarHandler
*/
@Test
public void testScalarHandler(){
Connection con = null;
QueryRunner queryRunner = new QueryRunner();
String sql = "SELECT I_D id,name FROM customer";
try {
con = JDBCTools.getConnection();
Object object = queryRunner.query(con, sql, new ScalarHandler<>(2));//返回查的的结果集中的2列的内容
System.out.println(object);//Tom
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.releaseDB(null, null, con);
}
}
}
JDBCTools类:
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
/**
* JDBC的工具类,利用数据库连接池连接数据库,以及相应的事务操作
* @author wushijia
*
*/
public class JDBCTools {
/**
* 提交事务
* @param con
*/
public static void commit(Connection con){
if(con != null){
try {
con.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 事务的回滚
* @param con
*/
public static void rollback(Connection con){
if(con != null){
try {
con.rollback();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 开始事务
* @param con
*/
public static void beginTransaction(Connection con){
if(con != null){
try {
con.setAutoCommit(false);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 利用静态代码块初始化数据库连接池,数据库连接池应该只被初始化一次
*/
public static DataSource datasource = null;
static{
Properties properties = new Properties();
InputStream in = JDBCTools.class.getClassLoader().getResourceAsStream("dbcp.properties");
try {
properties.load(in);
datasource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return datasource.getConnection();
}
/**
* 释放连接
* @param con
* @param state
* @param rs
*/
public static void releaseDB(ResultSet rs,Statement state,Connection con){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(state != null){
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(con != null){
try {
con.close();//释放连接只是将连接放回数据库连接池,供其它需要连接的事务使用
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Customer类
import java.sql.Date;
public class Customer {
public int id;
public String name;
public Date date;
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 Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public Customer(int id, String name, Date date) {
super();
this.id = id;
this.name = name;
this.date = date;
}
public Customer() {
super();
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", date=" + date + "]";
}
}