- 自定义连接池
普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密码(得花费0.05s~1s的时间)。需要数据库连接的时候,就向数据库要求一个,执行完成后再断开连接。这样的方式将会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用.若同时有几百人甚至几千人在线,频繁的进行数据库连接操作将占用很多的系统资源,严重的甚至会造成服务器的崩溃。连接池可以避免这些问题
实现步骤:
- 指定全局参数 : 初始化数目 最大连接数 当前连接 连接池集合
- 在构造函数中 : 循环创建三个连接
- 实现一个创建连接的方法
- 获取连接
- 关闭连接
代码部分:
package com.demo01.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
/**
* Created by pc on 17-5-1.
*/
public class MyPool {
private int init_count = 3; //初始化链接数目
private int max_count = 6; //最大连接数目
private int current_count; //记录连接数
//连接池,存放所有初始化连接
private LinkedList<Connection> pool = new LinkedList<Connection>();
//1.构造函数中将初始化连接放入连接池中
public MyPool() {
//初始化连接
for (int i = 0; i < init_count; i++) {
//记录当前连接条数
current_count++;
//把连接放入连接池中
pool.addLast(createConnection());
}
}
//2.创建一个新的连接对象
public Connection createConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
return DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//3.获取连接
public Connection getConnection() {
//判断连接池是否有连接,如果有则直接取出
if (pool.size() > 0) {
return pool.removeFirst();
}
//如果连接池的连接以取完,判断是否超过最大连接数,如果没有则创建
if (current_count < max_count) {
current_count++;
return createConnection();
}
//如果超过最大连接数,则抛出异常
throw new RuntimeException("超过最大连接数");
}
//4.释放链接
public void realeaseConnection(Connection connection) throws SQLException {
//如果连接池没有放满连接,则将该链接放回连接池
if (current_count < pool.size()) {
pool.addLast(connection);
current_count--;
} else {
connection.close();
current_count--;
}
}
}
- DBCP连接池
DBCP(DataBase connection pool)数据库连接池是 apache 上的一个Java连接池项目。DBCP通过连接池预先同数据库建立一些连接放在内存中(即连接池中),应用程序需要建立数据库连接时直接到从接池中申请一个连接使用,用完后由连接池回收该连接,从而达到连接复用,减少资源消耗的目的。
引入jar文件,使用maven配置这两个文件:
- commons-dbcp2
- commons-pool2
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.2</version>
</dependency>
代码部分
package com.demo01.test;
import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;
/**
* Created by pc on 17-5-1.
*/
public class Test_dbcp {
@Test
public void testDbcp() throws SQLException {
//DBCP连接池核心
BasicDataSource dataSource = new BasicDataSource();
//连接池参数配置:初始化连接数,最大连接数 /连接字符串,驱动,用户,密码
dataSource.setUrl("jdbc:mysql:///jdbcdemo?useUnicode=true&characterEncoding=utf-8");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setInitialSize(3);
dataSource.setMaxIdle(3000);
//dataSource.setMaxTotal(6);
//获取连接
Connection conn = dataSource.getConnection();
conn.prepareStatement("delete FROM admin where id=9").executeUpdate();
//关闭连接
conn.close();
}
}
image.png
- c3p0连接池
c3p0与dbcp区别
dbcp没有自动回收空闲连接的功能
c3p0有自动回收空闲连接功能
demo
package demo01.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.sql.Connection;
public class demo {
@Test
//1. 硬编码方式,使用C3P0连接池管理连接
public void testCode() throws Exception {
// 创建连接池核心工具类
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 设置连接参数:url、驱动、用户密码、初始连接数、最大连接数
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbcdemo");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setInitialPoolSize(3);
dataSource.setMaxPoolSize(6);
dataSource.setMaxIdleTime(1000);
// ---> 从连接池对象中,获取连接对象
Connection con = dataSource.getConnection();
// 执行更新
con.prepareStatement("delete from admin where id=7").executeUpdate();
// 关闭
con.close();
}
@Test
//2. XML配置方式,使用C3P0连接池管理连接
public void testXML() throws Exception {
// 创建c3p0连接池核心工具类
ComboPooledDataSource dataSource = new ComboPooledDataSource();// 使用默认的配置
// 获取连接
Connection con = dataSource.getConnection();
// 执行更新
con.prepareStatement("delete from admin where id=5").executeUpdate();
// 关闭
con.close();
}
}
原始数据表
操作后的数据表
网友评论
你需要思考一下,这里的异常我们应该怎么处理最好?
这行代码只需要调用一次,还是每一次都需要调用?
你这里新生成的连接不用放到池子里了吗?