Commons - dbutils
Posted WWWYC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Commons - dbutils相关的知识,希望对你有一定的参考价值。
时间:2016-12-4 18:06
——基本类
自己写的JDBC小工具:
public class JDBCUtils {
// 使用的是配置文件的默认配置,即必须给出c3p0-config.xml配置文件
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
/*
* 使用连接池返回一个连接对象
*/
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
/*
* 返回连接池对象
*/
public static DataSource getDataSource() {
return dataSource;
}
}
——JavaBean
package jdbcutils;
public class Stu {
private int sid;
private String sname;
private int age;
private String gender;
public Stu(int sid, String sname, int age, String gender) {
super();
this.sid = sid;
this.sname = sname;
this.age = age;
this.gender = gender;
}
public Stu() {
super();
}
@Override
public String toString() {
return "Stu [sid=" + sid + ", sname=" + sname + ", age=" + age + ", gender=" + gender + "]";
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
——使用commons - dbutils简化JDBC的代码
简化前:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.Test;
/**
* 使用commons-dbutils简化JDBC的代码
*/
public class Demo1 {
@Test
public void addStu(Stu stu) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "insert into t_stu values(?,?,?,?)";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, stu.getSid());
pstmt.setString(2, stu.getSname());
pstmt.setInt(3, stu.getAge());
pstmt.setString(4, stu.getGender());
} catch (Exception e) {
// 处理异常
} finally {
// 关闭连接
}
}
@Test
public void updateStu(Stu stu) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "update t_stu set sname = ?, age = ?, gender = ? where sid = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(4, stu.getSid());
pstmt.setString(1, stu.getSname());
pstmt.setInt(2, stu.getAge());
pstmt.setString(3, stu.getGender());
} catch (Exception e) {
// 处理异常
} finally {
// 关闭连接
}
}
@Test
public void deleteStu(Stu stu) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = JDBCUtils.getConnection();
String sql = "delete from t_stu where sid = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, stu.getSid());
} catch (Exception e) {
// 处理异常
} finally {
// 关闭连接
}
}
public Stu load(int sid) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = JDBCUtils.getConnection();
String sql = "select * from t_stu where sid = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, sid);
rs = pstmt.executeQuery();
/*
* 需要把rs转换成JavaBean
*/
if (rs.next()) {
Stu stu = new Stu();
stu.setSid(rs.getInt("sid"));
stu.setSname(rs.getString("sname"));
stu.setAge(rs.getInt("age"));
stu.setGender(rs.getString("gender"));
return stu;
}
} catch (Exception e) {
// 处理异常
} finally {
// 关闭连接
}
return null;
}
}
===============================================================================
简化后:
/*
* 用来将结果集转化成需要的类型
* 将结果集封装成一个对应的Bean并返回该Bean
*/
interface Rshandle<T> {
public T handle(ResultSet rs) throws SQLException;
}
------------------------------------------------------------------------------------------------------------------------------
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;
public class QR<T> {
/*
* 因为无法确定连接类型,所以使用DataSource接口来接收传入的连接对象
*/
private DataSource dataSource = null;
public QR() {
super();
}
public QR(DataSource dataSource) {
super();
/*
* 接收传入的连接对象
*/
this.dataSource = dataSource;
}
/*
* 更新操作 接收SQL模板和参数列表
*/
public int update(String sql, Object... params) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 通过连接池得到连接
conn = dataSource.getConnection();
// 使用SQL创建pstmt
pstmt = conn.prepareStatement(sql);
/*
* 给参数赋值
*/
initParams(pstmt, params);
// 执行SQL,并返回受影响行数
return pstmt.executeUpdate();
} catch (Exception e) {
// 处理异常
throw new RuntimeException(e);
} finally {
// 关闭连接
}
}
/*
* 使用传入的SQL语句和参数,最终得到一个结果集,然后调用结果集的handle()方法,handle()方法谁调用谁传入
*/
public T query(String sql, Rshandle<T> rh, Object... params) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
// 通过连接池得到连接
conn = dataSource.getConnection();
// 使用SQL创建pstmt
pstmt = conn.prepareStatement(sql);
// 给参数赋值
initParams(pstmt, params);
// 执行SQL
rs = pstmt.executeQuery();
// 将结果集传入指定的handle()方法中
return rh.handle(rs);
} catch (Exception e) {
// 处理异常
throw new RuntimeException(e);
} finally {
// 关闭连接
}
}
// 用来给参数赋值
private void initParams(PreparedStatement pstmt, Object... params) throws Exception {
for (int i = 0; i < params.length; i++) {
// 因为不知道参数的类型,所以使用Object接收参数
pstmt.setObject(i + 1, params[i]);
}
}
}
------------------------------------------------------------------------------------------------------------------------------
进行调用:
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
public class Demo2 {
@Test
public void fun1() {
// Stu s = new Stu(1001, "张三", 99, "male");
// int result = addStu(s);
// System.out.println("受影响行数:" + result);
Stu stu = load(1001);
System.out.println(stu);
}
public int addStu(Stu stu) {
// 创建对象时给出连接池
QR qr = new QR(JDBCUtils.getDataSource());
// 给出SQL模板
String sql = "insert into t_stu values(?,?,?,?)";
// 给出参数
Object[] params = { stu.getSid(), stu.getSname(), stu.getAge(), stu.getGender() };
// 调用update方法,执行增删改
return qr.update(sql, params);
}
public Stu load(int sid) {
// 创建QR对象,并给出连接池
QR<Stu> qr = new QR<Stu>(JDBCUtils.getDataSource());
// 创建SQL模板
String sql = "select * from t_stu where sid = ?";
// 给出参数
Object[] params = { sid };
// 使用RsHandle接口创建内部类
Rshandle<Stu> rh = new Rshandle<Stu>() {
// 重写handle()方法
public Stu handle(ResultSet rs) throws SQLException {
// 传入的rs集合如果是空,返回null
if (!rs.next()) {
return null;
}
// 如果不是null,组合对象并返回
Stu stu = new Stu();
stu.setSid(rs.getInt("sid"));
stu.setSname(rs.getString("sname"));
stu.setAge(rs.getInt("age"));
stu.setGender(rs.getString("gender"));
return stu;
}
};
/*
* 将SQL模板,内部类对象rh,参数列表传给查询方法query() 返回查询后得到的对象
*/
return qr.query(sql, rh, params);
}
}
------------------------------------------------------------------------------------------------------------------------------
commons-dbutils中的方法:
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.junit.Test;
public class Demo3 {
@Test
public void fun() throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "insert into t_stu values (?,?,?,?)";
Object[] params = { 1002, "李四", 88, "female" };
int result = qr.update(sql, params);
System.out.println("受影响行数:" + result);
}
@Test
public void fun2() throws Exception {
// 创建QueryRunner对象,并提供数据库连接池对象
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
// 给出SQL模板
String sql = "select * from t_stu where sid = ?";
// 给出参数
Object[] params = { 1002 };
// ResultSetHandler rsh = new ResultSetHandler(){
// @Override
// public Stu handle(ResultSet rs) throws SQLException {
// if(!rs.next()){
// return null;
//
// }
// return null;
// }
// }
// 执行query()方法,并给出结果集处理器,即ResultSetHandler接口的实现类
// 我们给出的是BeanHandler,它实现了ResultSetHandler接口
// 它需要一个类型,然后它会把结果集中的数据封装到指定类型的JavaBean对象中,然后返回JavaBean
Stu stu = qr.query(sql, new BeanHandler<Stu>(Stu.class), params);
System.out.println(stu);
}
}
——dbutils结果集处理器介绍
commons-dbutils.jar包
QueryRunner类:
update方法:
* int update(String sql, Object[] params)
可执行增删改语句。
* int update(Connection conn, String sql, Object ... params)
需要调用者提供Connection,这说明本方法不再管理Connection了。
这个方法的好处是可以使用同一Connection对象,用于处理事务,因为同一事务必须保证Connection是唯一的。而update(String sql, Object ... params)方法就无法保证事务的安全性,因为该方法是通过连接池来获取连接的。
即支持事务。
query方法:
* T query(String sql, ResultSetHandler rsh, Object ... params)
可执行查询。
它会先得到ResultSet,然后调用rsh的handle()方法并将rs结果集转换为需要的类型。
* T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object ... params)
道理同:update(Connection conn, String sql, Object ... params)
ResultSetHandler接口:
BeanHandler
处理单行结果集。
是一个实现类,构造器需要一个Class类型的参数,用来把一行结果集转换成指定类型的JavaBean对象。
BeanListHandler
处理多行结果集。
是一个实现类,构造器也需要一个Class类型的参数,用来把一行结果集转换成一个JavaBean对象,然后把多个JavaBean对象保存到List集合中。
MapHandler
处理单行结果集。
是一个实现类,无参构造,把一行结果集转换成Map对象。
> id 1001
> age 22
> name 张三
> gender 男
MapListHandler
处理多行记录。
是一个实现类,无参构造,把一行记录转换成一个Map对象,多行就是多个Map对象,然后将Map对象保存到List中。
ScalarHandler
单行单列时使用。
通常用于:select count(*) from table语句,即结果集是单行单列的,它返回一个Object。
——结果集处理器具体操作
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.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
public class Result2 {
/*
* BeanListHandler的应用,它是多行结果集处理器 每行记录对应一个Student对象
*/
@Test
public void fun() throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from t_stu";
List<Student> list = qr.query(sql, new BeanListHandler<Student>(Student.class));
System.out.println(list);
}
/*
* MapHandler的应用,它是单行处理器,把一行转换成一个Map对象
*/
@Test
public void fun2() throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from t_stu where sid = ?";
Object[] params = { 2 };
Map<String, Object> map = qr.query(sql, new MapHandler(), params);
System.out.println(map);
}
/*
* MapListHandler的应用,它是多行处理器,把每行都转换成一个Map,即List<Map>
*/
@Test
public void fun3() throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from t_stu";
List<Map<String, Object>> mapList = qr.query(sql, new MapListHandler());
System.out.println(mapList);
}
/*
* ScalarHandler的应用,返回单行单列的数据
*/
@Test
public void fun4() throws Exception {
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select count(*) from t_stu";
Object obj = qr.query(sql, new ScalarHandler());
System.out.println(obj);
// 打印Object的类型
System.out.println(obj.getClass().getName());
/*
* 在JDBC5.1之前,query返回的是Integer类型,在Oracle中返回的是BigInteger类型
* 而在JDBC5.1之后,
mysql返回的是Long类型,这三个类有一个共同的父类:Number
* 所以可以使用Number来接收,然后根据需求转换即可。
*/
Number number = (Number) qr.query(sql, new ScalarHandler());
int i = number.intValue();
long l = number.longValue();
System.out.println(i);
System.out.println(l);
}
}
以上是关于Commons - dbutils的主要内容,如果未能解决你的问题,请参考以下文章
commons-lang3
commons-beanutils的jar包导入了出错。Java 一直报下图错误
commons字符串工具类——commons-lang3
Commons-Collections漏洞
commons dbcp.jar有什么用
Commons Lang 介绍