一、前言:
C3P0是存放了一堆Connection对象的连接池。避免了java每次加载驱动和连接数据库;DbUtils简化了Java执行sql的语句,并将结果封装成对象列表。
1、Dbutils是什么
Dbutils:主要是封装了JDBC的代码,简化dao层的操作。
作用:帮助java程序员,开发Dao层代码的简单框架。
框架的作用:帮助程序员,提高程序的开发效率。
Dbutils是由Apache公司提供。
2、为什么需要Dbutils :
在使用Dbutils 之前,我们Dao层使用的技术是JDBC,那么分析一下JDBC的弊端:
(1)数据库链接对象、sql语句操作对象,封装结果集对象,这三大对象会重复定义
(2)封装数据的代码重复,而且操作复杂,代码量大
(3)释放资源的代码重复
结果:(1)程序员在开发的时候,有大量的重复劳动。(2)开发的周期长,效率低
3、Dbutils三个核心类介绍:
1)DbUtils:连接数据库对象----jdbc辅助方法的集合类,线程安全
构造方法:DbUtils()
作用:控制连接,控制书屋,控制驱动加载额一个类。
2)QueryRunner:SQL语句的操作对象,可以设置查询结果集的封装策略,线程安全。
构造方法:
(1)QueryRunner():创建一个与数据库无关的QueryRunner对象,后期再操作数据库的会后,需要手动给一个Connection对象,它可以手动控制事务。
Connection.setAutoCommit(false); 设置手动管理事务
Connection.commit(); 提交事务
(2)QueryRunner(DataSource ds):创建一个与数据库关联的queryRunner对象,后期再操作数据库的时候,不需要Connection对象,自动管理事务。
DataSource:数据库连接池对象。
构造函数与增删改查方法的组合:
QueryRunner()
update(Connection conn, String sql, Object... params)
query(Connection conn, String sql,ResultSetHandler
QueryRunner(DataSource ds)
update(String sql, Object... params)
query(String sql, ResultSetHandler
(3)ResultSetHandle:封装数据的策略对象------将封装结果集中的数据,转换到另一个对象
策略:封装数据到对象的方式(示例:将数据库保存在User、保存到数组、保存到集合)
方法介绍:handle(ResultSet rs)
备注:详解参考ResultSetHandle实现类
二、话不多说,直接上demo,帮忙点赞,有问题,欢迎留言讨论 :
在src或者resource目录创建c3po连接池配置文件:
jdbc:mysql://localhost:3306/ocs?useUnicode=true&characterEncoding=utf-8
com.mysql.jdbc.Driver
root
root
3
10
2
10
package com.jason.support;
import org.apache.commons.dbutils.QueryRunner;
/**
* @program: JasonDbUtil
* @description
* @author: 大龄程序猿
* @create: 2020-05-10 23:52
**/
public class DbUtilTemplate {
private static final ThreadLocal qr=new ThreadLocal();
private static Object lock=new Object();
private DbUtilTemplate()
{
}
public static QueryRunner getQueryRunner()
{
if(qr.get()!=null)
{
return qr.get();
}
QueryRunner runner=null;
synchronized (lock)
{
if(qr.get()==null)
{
runner = new QueryRunner(JdbcUtils.getDataSource());
qr.set(runner);
return runner;
}
}
return qr.get();
}
}
package com.jason.support;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @program: JasonDbUtil
* @description
* @author: 大龄程序猿
* @create: 2020-05-10 23:54
**/
public class JdbcUtils {
// 饿汉式
private static DataSource ds = new ComboPooledDataSource();
/**
* 它为null表示没有事务
* 它不为null表示有事务
* 当开启事务时,需要给它赋值
* 当结束事务时,需要给它赋值为null
* 并且在开启事务时,让dao的多个方法共享这个Connection
*/
private static ThreadLocal tl = new ThreadLocal();
public static DataSource getDataSource() {
return ds;
}
// 如果不把c3p0配置文件放在src或resource下的话,就使用如下方式加载
// static {
// try {
// Properties prop = new Properties();
// InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
// prop.load(in);
// BasicDataSourceFactory factory = new BasicDataSourceFactory();
// ds = factory.createDataSource(prop);
// } catch (Exception e) {
// throw new ExceptionInInitializerError(e);
// }
// }
/**
* dao使用本方法来获取连接
*/
public static Connection getConnection() throws SQLException {
/*
* 如果有事务,返回当前事务的con
* 如果没有事务,通过连接池返回新的con
*/
Connection con = tl.get();//获取当前线程的事务连接
if (con != null) return con;
return ds.getConnection();
}
/**
* 开启事务
*/
public static void beginTransaction() throws SQLException {
Connection con = tl.get();//获取当前线程的事务连接
if (con != null) throw new SQLException("已经开启了事务,不能重复开启!");
con = ds.getConnection();//给con赋值,表示开启了事务
con.setAutoCommit(false);//设置为手动提交
tl.set(con);//把当前事务连接放到tl中
}
/**
* 提交事务
*/
public static void commitTransaction() throws SQLException {
Connection con = tl.get();//获取当前线程的事务连接
if (con == null) throw new SQLException("没有事务不能提交!");
con.commit();//提交事务
con.close();//关闭连接
con = null;//表示事务结束!
tl.remove();
}
/**
* 回滚事务
*/
public static void rollbackTransaction() throws SQLException {
Connection con = tl.get();//获取当前线程的事务连接
if (con == null) throw new SQLException("没有事务不能回滚!");
con.rollback();
con.close();
con = null;
tl.remove();
}
/**
* 释放Connection
*/
public static void releaseConnection(Connection connection) throws SQLException {
Connection con = tl.get();//获取当前线程的事务连接
if (connection != con) {//如果参数连接,与当前事务连接不同,说明这个连接不是当前事务,可以关闭!
if (connection != null && !connection.isClosed()) {//如果参数连接没有关闭,关闭之!
connection.close();
}
}
}
public static void main(String[] args) {
try {
System.out.println(JdbcUtils.getConnection());
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package com.jason.bean;
import java.io.Serializable;
/**
* @program: mybatis
* @description
* @author: 大龄程序猿
* @create: 2020-05-06 23:43
**/
public class Employee implements Serializable {
private long id;
private String name;
private String email;
private String password;
private String birthday;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
private int age;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
测试类:
package com.jason.dao;
import com.jason.bean.Employee;
import com.jason.support.DbUtilTemplate;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
/**
* @program: JasonDbUtil
* @description
* @author: 大龄程序猿
* @create: 2020-05-11 00:23
**/
public class EmployeeDao {
@Test
public void insert() throws SQLException {
QueryRunner runner = DbUtilTemplate.getQueryRunner();
String sql = "insert into employee(id,name,password,email,birthday) values(?,?,?,?,?)";
Object[] params = {2, "bbb", "123", "[email protected]", new Date()};
runner.update(sql, params);
}
@Test
public void find() throws SQLException {
QueryRunner runner = DbUtilTemplate.getQueryRunner();
String sql = "select * from employee where id=?";
Employee user = (Employee) runner.query(sql, 2, new BeanHandler(Employee.class));
System.out.println(user.getEmail());
}
@Test
public void update() throws SQLException {
QueryRunner runner = DbUtilTemplate.getQueryRunner();
String sql = "update employee set email=? where id=?";
Object[] params = {"[email protected]", 2};
runner.update(sql, params);
}
@Test
public void delete() throws SQLException {
QueryRunner runner = DbUtilTemplate.getQueryRunner();
String sql = "delete from employee where id=?";
runner.update(sql, 32);
}
@Test
public void getAll() throws SQLException {
QueryRunner runner = DbUtilTemplate.getQueryRunner();
String sql = "select * from employee";
List list = (List) runner.query(sql, new BeanListHandler(Employee.class));
System.out.println(list);
}
@Test
public void batch() throws SQLException {
QueryRunner runner = DbUtilTemplate.getQueryRunner();
String sql = "insert into employee(id,name,password,email,birthday) values(?,?,?,?,?)";
Object[][] params = new Object[3][5];
for (int i = 0; i < params.length; i++) {
params[i] = new Object[]{i+1, "aa"+i, "123", i+"@sian.com", new Date()};
}
runner.batch(sql, params);
}
}