- 学习目标
- 数据库连接池
- 数据库连接池原理
- 第一步
- 第二步
- 第三步
- 第四步
- 第五步
- DBCP
- DBCP参数
- 方法1
- 方法2
- C3P0
- 方法1
- 方法2
- DbUtils
- QueryRunner核心类
- ResultSetHandler结果集处理类
- 案例
- 查询
- 其他方法
- 作业
- 模拟数据库连接池
- DBCP 连接池
- C3P0连接池
- 了解数据库连接池的原理
- 了解C3P0数据库连接池
- 了解DBCP数据库连接池
- 掌握Druid数据库连接池
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的N个(自定义)数据库连接,不用每次都再重新建立一个新的连接,以提高对数据库操作的性能。
常用开源的数据库连接池
- C3P0:是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate [2] 一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
- Proxool:是一个Java SQDriver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。
- Jakarta DBCP:DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。
-DBPool:是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。 - SmartPool:是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks)、连接阻塞、打开的JDBC对象(如Statements、PreparedStatements)等。
- Druid连接池是阿里巴巴开源的数据库连接池项目。Druid连接池为监控而生,内置强大的监控功能,监控特性不影响性能。功能强大,能防SQL注入,内置Loging能诊断Hack应用行为。
简单来说,数据库连接池就是在一开始先创建N多个数据库连接connection对象,存储在一个集合内,每次使用一个就从集合内取出一个,用完之后又添加到集合内,一直反复使用。
第一步创建带有是否使用标记的Connection对象。自定义一个带有是否使用标记的Connection对象。
package com.pool;
import java.sql.Connection;
public class PooledConnection {
// 数据库连接
private Connection conn;
// 用于标识当前数据库连接的状态 true:执行 false:空闲
private boolean busy;
public PooledConnection(Connection conn) {
this.conn = conn;
}
public Connection getConn() {
return conn;
}
public void setConn(Connection conn) {
this.conn = conn;
}
public boolean isBusy() {
return busy;
}
public void setBusy(boolean busy) {
this.busy = busy;
}
}
第二步
创建数据库线程池对象
数据库线程池对象包含默认连接数、最大连接数、每次新增个数、超时时间和连接对象集合。
package com.star;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.*;
public class Poo{
// 初始化连接数
private static int initSize = 2;
// 池中最大连接数
private static int maxSize = 10;
// 每次创建的连接数
private static int stepSize = 2;
// 超时时间
private static int timeout = 2000;
// 用来保存创建的数据库连接
private static List poo= Collections.synchronizedList(new ArrayList<>());
//单例对象
private static Pooinstance;
private Pool() {
resizePool(initSize);
}
private Pool() {
resizePool(initSize);
}
public static synchronized PoogetInstance() {
if (instance == null) {
instance = new Pool();
}
return instance;
}
private void resizePool(int size) {
int current = pool.size();
if (current + size > maxSize) {
size = maxSize - current;
}
for (int i = 0; i < size; i++) {
pool.add(new PoolCollection(createConnection()));
}
}
}
第三步
获取连接
public Connection createConnection() {
try {
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//加载配置文件
Properties p = new Properties();
p.load(new FileInputStream("jdbc.properties"));
return DriverManager.getConnection(p.getProperty("url"), p.getProperty("user"), p.getProperty("password"));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Connection getConnection() {
Connection connection = getAddConnection();
while (connection == null) {
System.out.println(Thread.currentThread().getName() + "开始等待获取连接");
try {
Thread.sleep(timeout);
connection = getAddConnection();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "拿到连接");
return connection;
}
private Connection getAddConnection() {
Connection connection = getUsableConnection();
if (connection == null) {
resizePool(stepSize);
connection = getUsableConnection();
}
return connection;
}
private Connection getUsableConnection() {
Connection connection = null;
if (pool.size() > 0) {
for (PoolCollection poolCollection : pool) {
if (poolCollection.isUsed() == false) {
poolCollection.setUsed(true);
connection = poolCollection.getConnection();
//connection有课能在上次使用过程中产生异常被中断
try {
// connection.isValid如果连接未关闭且有效,则返回true
if (connection.isValid(2000) == false) {
connection = createConnection();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
break;
}
}
}
return connection;
}
第四步
归还
public void close(Connection connection){
for (PoolCollection poolCollection : pool) {
if(connection == poolCollection.getConnection()){
poolCollection.setUsed(false);
}
}
}
第五步
测试
package com.star;
import java.sql.Connection;
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 20; i++) {
new Thread(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "获取连接");
Poopool1 = Pool.getInstance();
Connection connection = pool1.getConnection();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
pool1.close(connection);
System.out.println(Thread.currentThread().getName() + "释放连接");
}
}.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
DBCP
下载DBCP地址:
下载pool地址
下载Logging地址
DBCP参数| 参数 | 默认值 | 说明 |
|---|---|---|
| username | 传递给JDBC驱动的用于建立连接的用户名 | |
| password | 传递给JDBC驱动的用于建立连接的密码 | |
| url | 传递给JDBC驱动的用于建立连接的URL | |
| driverClassName | 使用的JDBC驱动的完整有效的Java 类名 | |
| initialSize | 0 | 初始化连接:连接池启动时创建的初始化连接数量,1.2版本后支持 |
| maxActive | 8 | 最大活动连接:连接池在同一时间能够分配的最大活动连接的数量, 如果设置为非正数则表示不限制 |
| maxIdle | 8 | 最大空闲连接:连接池中容许保持空闲状态的最大连接数量,超过的空闲连接将被释放, 如果设置为负数表示不限制 |
| minIdle | 0 | 最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接, 如果设置为0则不创建 |
| maxWait | 无限 | 最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间(以毫秒计数)超过时间则抛出异常,如果设置为-1表示无限等待 |
| testOnReturn | false | 是否在归还到池中前进行检验 |
| testWhileIdle | false | 连接是否被空闲连接回收器(如果有)进行检验.如果检测失败, 则连接将被从池中去除.设置为true后如果要生效,validationQuery参数必须设置为非空字符串 |
| minEvictableIdleTimeMillis | 1000 * 60 * 30 | 连接在池中保持空闲而不被空闲连接回收器线程 (如果有)回收的最小时间值,单位毫秒 |
| numTestsPerEvictionRun | 3 | 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 |
| timeBetweenEvictionRunsMillis | -1 | 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. 如果设置为非正数,则不运行空闲连接回收器线程 |
| validationQuery | null | SQL查询,用来验证从连接池取出的连接,在将连接返回给调用者之前.如果指定, 则查询必须是一个SQSELECt并且必须返回至少一行记录 |
| testOnBorrow | true | 是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个. |
package com.dbcp;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
public class DBCPUtils {
private String driver = "com.mysql.cj.jdbc.Driver";
private String ur= "jdbc:mysql://localhost/mydbcp?serverTimezone=GMT";
private String username = "root";
private String password = "";
private static BasicDataSource basicDataSource = new BasicDataSource();
public DBCPUtils() {
basicDataSource.setUrl(url);
basicDataSource.setDriverClassName(driver);
basicDataSource.setUsername(username);
basicDataSource.setPassword(password);
basicDataSource.setInitialSize(10);// 初始化时创建10个链接
basicDataSource.setMaxIdle(8);// 设置最大连接数
basicDataSource.setMaxIdle(5);// 这只最大的空闲连接数
basicDataSource.setMinIdle(1);// 设置最小空闲连接数字
}
public static DataSource getDataSource() {
return basicDataSource;
}
}
测试
package com.dbcp;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.sql.DataSource;
public class DBCPTest {
public static void main(String[] args) {
DBCPUtils uti= new DBCPUtils();
DataSource ds = util.getDataSource();
Connection conn;
try {
conn = ds.getConnection();
String sq= "insert into user values(null,?,?,?,?)";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, "王麻子");
st.setInt(2, 1);
st.setDate(3, new Date(new SimpleDateFormat("yyyy-MM-dd").parse("2019-06-08").getTime()));
st.setInt(4, 1);
int i = st.executeUpdate();
if (i == 1) {
System.out.println("success");
} else {
System.out.println("fail");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
方法2
配置文件dbcp.properties
#驱动名
driverClassName=com.mysql.cj.jdbc.Driver
#数据库
database=mydbcp
#url
url=jdbc:mysql://localhost/${database}?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
#用户名
username=root
#密码
password=
#初试连接数
initialSize=30
#最大活跃数
maxTotal=30
#最大idle数
maxIdle=10
#最小idle数
minIdle=5
#最长等待时间(毫秒)
maxWaitMillis=1000
#程序中的连接不使用后是否被连接池回收(该版本要使用removeAbandonedOnMaintenance和removeAbandonedOnBorrow)
#removeAbandoned=true
removeAbandonedOnMaintenance=true
removeAbandonedOnBorrow=true
#连接在所指定的秒数内未使用才会被删除(秒)(为配合测试程序才配置为1秒)
removeAbandonedTimeout=1
使用
package com.dbcp;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
public class DBCPUtils2 {
private static BasicDataSource basicDataSource = new BasicDataSource();
public DBCPUtils2() {
Properties prop = new Properties();
try {
prop.load(new FileInputStream("src/dbcp.properties"));
basicDataSource = new BasicDataSourceFactory().createDataSource(prop);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource() {
return basicDataSource;
}
}
测试
package com.dbcp;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.sql.DataSource;
public class DBCPTest2 {
public static void main(String[] args) {
DBCPUtils2 uti= new DBCPUtils2();
DataSource ds = util.getDataSource();
Connection conn;
try {
conn = ds.getConnection();
String sq= "insert into user values(null,?,?,?,?)";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, "王麻子");
st.setInt(2, 1);
st.setDate(3, new Date(new SimpleDateFormat("yyyy-MM-dd").parse("2019-06-08").getTime()));
st.setInt(4, 1);
int i = st.executeUpdate();
if (i == 1) {
System.out.println("success");
} else {
System.out.println("fail");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
C3P0
下载C3P0地址:
方法1package com.c3p0;
import java.beans.PropertyVetoException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0Utils {
private static ComboPooledDataSource cpds = null;
public C3P0Utils() {
cpds = new ComboPooledDataSource();
try {
cpds.setDriverClass("com.mysql.cj.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql://localhost/mydbcp?serverTimezone=GMT");
cpds.setUser("root");
cpds.setPassword("");
cpds.setMinPoolSize(5);
cpds.setMaxPoolSize(20);
cpds.setAcquireIncrement(5);
cpds.setInitialPoolSize(5);
cpds.setMaxStatements(50);
cpds.setMaxIdleTime(60);
} catch (PropertyVetoException e) {
e.printStackTrace();
}
}
public static ComboPooledDataSource getDataSource() {
return cpds;
}
}
测试
package com.c3p0;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.sql.DataSource;
public class C3P0Test {
public static void main(String[] args) {
C3P0Utils uti= new C3P0Utils();
DataSource ds = util.getDataSource();
Connection conn;
try {
conn = ds.getConnection();
String sq= "insert into user values(null,?,?,?,?)";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, "王麻子");
st.setInt(2, 1);
st.setDate(3, new Date(new SimpleDateFormat("yyyy-MM-dd").parse("2019-06-08").getTime()));
st.setInt(4, 1);
int i = st.executeUpdate();
if (i == 1) {
System.out.println("success");
} else {
System.out.println("fail");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
方法2
配置文件夹,通过 c3p0-config.xml文件进行配置,文件名不能改
root root jdbc:mysql://localhost/mydbcp? serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=false com.mysql.cj.jdbc.Driver 30000 30 5 60 20 5 50 5 Xiaopengwei 123456 jdbc:mysql://localhost:3306/Xiaopengwei com.mysql.jdbc.Driver 5 20 25 5
使用
package com.c3p0;
import java.beans.PropertyVetoException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0Utils2 {
private static ComboPooledDataSource cpds = null;
public C3P0Utils2() {
cpds = new ComboPooledDataSource();
}
public static ComboPooledDataSource getDataSource() {
return cpds;
}
}
测试
package com.c3p0;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import javax.sql.DataSource;
public class C3P0Test2 {
public static void main(String[] args) {
C3P0Utils2 uti= new C3P0Utils2();
DataSource ds = util.getDataSource();
Connection conn;
try {
conn = ds.getConnection();
String sq= "insert into user values(null,?,?,?,?)";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, "王麻子");
st.setInt(2, 1);
st.setDate(3, new Date(new SimpleDateFormat("yyyy-MM-dd").parse("2019-06-08").getTime()));
st.setInt(4, 1);
int i = st.executeUpdate();
if (i == 1) {
System.out.println("success");
} else {
System.out.println("fail");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
DbUtils
DbUtils是在数据库连接池基础上建立起来的快速操作数据库的工具类。
后面会用到spring JdbcTemplate、Mybatis、hibernate等框架
下载地址:
DBUtils三个核心功能介绍
-QueryRunner中提供对sql语句操作的API
- ResultSetHandler接口,用于定义select操作后,怎样封装结果集
- DBUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法
QueryRunner(DataSource ds),传入连接池,并且底层自动维护连接connection
-update(String sql,Obj...params),执行更新数据
- query(String sql,ResultSetHandler rsh,Object...panrams),执行查询
-ArrayHandler:适合取1条记录,把结果集中的第一行数据转成对象数组。
- ArrayListHandler:适合取多条记录,把结果集中的每一行数据都转成一个对象数组,再存放到List中。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中(把每条记录封装成对象,适合取一条记录)
-BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。 - MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
- KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(Map
- ScalarHandler:将结果集第一行的某一列放到某个对象Object中。
实体类
package com.dbutils.entity;
import java.sql.Date;
public class User {
private Long id;
private String name;
private Boolean sex;
private Date birthday;
private Integer status;
public User() {
super();
}
public User(Long id, String name, Boolean sex, Date birthday, Integer status) {
super();
this.id = id;
this.name = name;
this.sex = sex;
this.birthday = birthday;
this.status = status;
}
public User(String name, Boolean sex, Date birthday) {
super();
this.name = name;
this.sex = sex;
this.birthday = birthday;
}
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 Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}
查询
package com.dbutils;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.KeyedHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.jupiter.api.Test;
import com.dbutils.entity.User;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class MyDbUtils {
// --1.ArrayHandler:将查询的结果的第一行放到一个数组中
@Test
public void query1() throws SQLException {
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
Object[] array = runner.query("select * from user", new ArrayHandler());
System.out.println(array[0] + "," + array[1]);
}
// --2.ArrayListHandler:将查询的结果的每一行放到一个数组中,然后再将数组放到集合中;
@Test
public void query2() throws SQLException {
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
List
其他方法
- close():
- DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭连接、声明和结果集(ResultSet)。
-CloseQuietly: - CloseQuietly这一方法不仅能在连接、声明或者结果集(ResultSet)为NULL情况下避免关闭,还能隐藏一些在程序中抛出的SQLEeception。
- 如果你不想捕捉这些异常的话,这对你是非常有用的。
- 在重载CloseQuietly方法时,特别有用的一个方法是closeQuietly(Connection conn,Statement stmt,ResultSet rs),这是因为在大多数情况下,连接、声明和结果集(ResultSet)是你要用的三样东西,而且在最后的块你必须关闭它们。
- 使用这一方法,你最后的块就可以只需要调用这一方法即可。
- DbUtils类提供了三个重载的关闭方法。这些方法检查所提供的参数是不是NULL,如果不是的话,它们就关闭连接、声明和结果集(ResultSet)。
- CommitAndCloseQuietly(Connection conn):
- 这一方法用来提交连接,然后关闭连接,并且在关闭连接时不向上抛出在关闭时发生的一些SQL异常。
- LoadDriver(String driveClassName):这一方法装载并注册JDBC驱动程序,如果成功就返回TRUE。
- 使用这种方法,你不需要去捕捉这个异常ClassNotFoundException。使用loadDrive方法,编码就变得更容易理解,
- 你也就得到了一个很好的Boolean返回值,这个返回值会告诉你驱动类是不是已经加载成功了。
package utility;
import Entity.User;
import MapperEntity.UserMapperEntity;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import java.io.FileInputStream;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class DBCPUtility {
private static BasicDataSource basicDataSource;
//加载配置文件
static {
Properties properties = new Properties();
try (
FileInputStream fis = new FileInputStream("dbpc.properties");
) {
properties.load(fis);
basicDataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static List executeQuery(String sql,Object ... params) {
Connection connection = getConnection();
PreparedStatement statement=null;
List list = new ArrayList<>();
if (connection==null) {
return null;
}
try {
connection.setAutoCommit(false);
statement=connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
statement.setObject(i+1,params[i]);
}
ResultSet resultSet = statement.executeQuery();
list = UserMapperEntity.getUser(resultSet);
connection.commit();
} catch (SQLException throwables) {
throwables.printStackTrace();
try {
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
Close(connection,statement);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return list;
}
public static int executeUpdate(String sql,Object ... params) {
Connection connection = getConnection();
PreparedStatement statement=null;
int rows=0;
List list = new ArrayList<>();
if (connection==null) {
return rows;
}
try {
connection.setAutoCommit(false);
statement=connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
statement.setObject(i+1,params[i]);
}
rows = statement.executeUpdate();
connection.commit();
} catch (SQLException throwables) {
throwables.printStackTrace();
try {
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
Close(connection,statement);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return rows;
}
public static Connection getConnection(){
try {
return basicDataSource.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
public static void Close(Connection connection) throws SQLException {
if (connection != null) {
connection.close();
}
}
public static void Close(Statement statement) throws SQLException {
if (statement != null) {
statement.close();
}
}
public static void Close(Connection connection,Statement statement) throws SQLException {
connection.close();
statement.close();
}
}
C3P0连接池
package utility;
import Entity.User;
import MapperEntity.UserMapperEntity;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class C3P0Utility {
private static final ComboPooledDataSource dataSource;
static{
dataSource=new ComboPooledDataSource();
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException throwables)
{
throwables.printStackTrace();
}
return null;
}
public static List executeQuery(String sql,Object ... params){
Connection connection = getConnection();
PreparedStatement statement=null;
List list = new ArrayList<>();
if (connection==null) {
return null;
}
try {
connection.setAutoCommit(false);
statement=connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
statement.setObject(i+1,params[i]);
}
ResultSet resultSet = statement.executeQuery();
list = UserMapperEntity.getUser(resultSet);
connection.commit();
} catch (SQLException throwables) {
throwables.printStackTrace();
try {
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}finally {
Close(connection,statement);
}
}
return list;
}
public static int executeUpdate(String sql,Object ... params){
Connection connection = getConnection();
PreparedStatement statement=null;
int rows=0;
if (connection==null) {
return rows;
}
try {
connection.setAutoCommit(false);
statement=connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
statement.setObject(i+1,params[i]);
}
rows = statement.executeUpdate();
connection.commit();
} catch (SQLException throwables) {
throwables.printStackTrace();
try {
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}finally {
Close(connection,statement);
}
}
return rows;
}
public static void Close(Connection connection){
if (connection!=null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void Close(Statement statement){
if(Objects.nonNull(statement)){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void Close(Connection connection,Statement statement){
Close(connection);
Close(statement);
}
}



