说到我们公司的连接池的话
1首先需要提到我们公司提供的连接池准则
2在这个准则里一共有五个方法
3第一个是初始化 第二个是获取链接 第三个是归还链接 第四个是创建连接 第五个是关闭连接
初始化连接池
那么初始化的话我们其实是调用了我们连接池的实现类的一个方法 我们这里初始化的是初始连接数 那么我们需要什么样的参数 就拿我们公司的mysql连接池来说 那么在mysql连接池实现类里面 一共有四个参数 分别是 空闲队列 活动队列 记录队列的连接总数 以及mysql的基础配置 这个基础配置里就包括mysql地址 端口 库名 端口等一系列 所有的mysql的基础信息 还有初始化多少 最大连接数多少 最大等待时间这些 那么我们调用init方法的时候 就从这个配置里面 拿到 我们这些信息去进行创建连接 创建连接数的数量就是刚才说的这个初始连接数 那初始化完成之后 两个队列需要初始化 两个队列的长度就是我们连接基础信息里面的最大长度
获取连接
那么我们在初始化完成之后我们就可以去进行获取链接 获取链接的话从空闲队列中获取然后放入活动队列 那么这个时候会有两个情况 第一种情况是有 有的话是直接返回 第二种情况是没有 没有的话我们要去判断一下 它是否达到最大连接数 如果达到的话去进行自旋 自旋的过程中也有两种情况 一种是在规定的时间内自旋到了连接 另一种是 在自旋的过程中没有拿到连接 如果没有拿到连接的话会抛出“获取连接超时”的异常 获取连接完了之后
归还链接
还有归还链接 归还链接就是删除活动队列中的 连接 把这个连接放到空闲队列中
创建链接
再往后的话是 创建链接 这个创建连接为什么要进行单独开放呢 因为有的时候 我们做了一个预留 这个预留就是我们数据的一个补救策略 就我们的连接一直获取不到 尝试三次以上的话 我们会手动的单独去连接一次 但是这个连接只使用一次 那么这个连接完了之后呢
关闭连接
最后有一个关闭连接 关闭连接的话 我们使用递归的形式去进行关闭 关闭的是两个队列当中的连接信息
下面代码
MysqlPollConfig
import com.poll.BaseConfig;
/**
* @author : 王龄凯
* @date : 2021/5/21 14:27
**/
public class MysqlPollConfig {
//id
private String id;
//初始化连接数
private int initTotal;
//最大连接数
private int maxTotal;
//最长等待时间
private long maxWaitTime;
//驱动
private String driverName;
//url ip 端口 数据库 编码
private String ip;
private int port;
private String databaseName;
private String param;
//用户名
private String userName;
//密码
private String password;
public String getUrl(){
StringBuilder urlsb = new StringBuilder(BaseConfig.MYSQLJDBCPRO);
urlsb.append(this.ip);//jdbc:mysql://127.0.0.1
urlsb.append(":");//jdbc:mysql://127.0.0.1:
urlsb.append(this.port);//jdbc:mysql://127.0.0.1:3306
urlsb.append("/");//jdbc:mysql://127.0.0.1:3306/
urlsb.append(this.databaseName);//jdbc:mysql://127.0.0.1:3306/etl
urlsb.append("?");//jdbc:mysql://127.0.0.1:3306/etl?
urlsb.append(this.param);//jdbc:mysql://127.0.0.1:3306/etl?serverTimezone=UTC&characterEncoding=utf-8
return urlsb.toString();
}
public int getInitTotal() {
return initTotal;
}
public void setInitTotal(int initTotal) {
this.initTotal = initTotal;
}
public int getMaxTotal() {
return maxTotal;
}
public void setMaxTotal(int maxTotal) {
this.maxTotal = maxTotal;
}
public long getMaxWaitTime() {
return maxWaitTime;
}
public void setMaxWaitTime(long maxWaitTime) {
this.maxWaitTime = maxWaitTime;
}
public String getDriverName() {
return driverName;
}
public void setDriverName(String driverName) {
this.driverName = driverName;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDatabaseName() {
return databaseName;
}
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
MysqlConnException
/**
* @author : 王龄凯
* @date : 2021/5/21 16:24
**/
public class MysqlConnException extends RuntimeException {
public MysqlConnException(String message) {
super(message);
}
}
BaseConfig
public class BaseConfig {
/**
* mysql连接的前缀
*/
public static final String MYSQLJDBCPRO = "jdbc:mysql://";
public static void driver(String dirverName){
try {
Class.forName(dirverName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
BasePoll
/**
* @author 王龄凯
* @Classname Basepoll
* @Description TODO
* @Date 2021/5/20
*
* 提供了一个连接池的准则
*/
public interface BasePoll<T> {
/**
* 初始化
*/
public void init();
/**
* 获取连接
* @return
*/
public T getConn();
/**
* 归还连接
* @param conn
*/
public void replease(T conn);
/**
* 创建连接
* @return
*/
public T createCon();
/**
* 关闭连接
*/
public void closeConn();
}
mysqlpoll
import com.poll.BaseConfig;
import com.poll.BasePoll;
import com.poll.Mysql;
import com.poll.config.MysqlPollConfig;
import com.poll.exeption.MysqlConnException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author : 王龄凯
* @date : 2021/5/21 14:53
**/
public class MysqlPoll implements BasePoll<Connection> {
private static final Logger log = LoggerFactory.getLogger(Mysql.class);
//空闲队列
private Queue<Connection> mysqlConnQueue = null;
//活动队列
private Queue<Connection> activeMysqlConnQueue = null;
//记录队列的连接总数
private AtomicInteger count = new AtomicInteger();
//mysql配置
public MysqlPollConfig mysqlpollConfig;
//实例化连接池 加载驱动
public MysqlPoll(MysqlPollConfig mysqlpollConfig){
this.mysqlpollConfig = mysqlpollConfig;
BaseConfig.driver(mysqlpollConfig.getDriverName());
log.info("mysql连接池实例化完成");
}
//初始化连接池
@Override
public void init() {
int maxTotal = this.mysqlpollConfig.getMaxTotal();
int initTotal = this.mysqlpollConfig.getInitTotal();
this.mysqlConnQueue = new LinkedBlockingQueue<Connection>(maxTotal);
this.activeMysqlConnQueue = new LinkedBlockingQueue<Connection>(initTotal);
for (int i = 0; i < initTotal; i++) {
this.mysqlConnQueue.offer(createCon());
count.incrementAndGet();
}
log.info("mysql连接池初始化完成");
}
//1.获取当前毫秒 计算时间是否超时
//2.判断队列当中是否还有空闲连接
//3.如果有连接,获取连接进行返回
//4.如果没有连接,判断是否达到最大连接数
//5.如果达到最大连接数量,就进行等待
//6.如果没有达到最大连接数量,进行创建一个连接
//7.放入使用队列当中,然后进行返回
//8.如果连接超时的话,就进行抛出异常
@Override
public Connection getConn() {
long startTime = System.currentTimeMillis();
while (true){
//从空闲队列当中放入活动队列
Connection conn = this.mysqlConnQueue.poll();
if(conn!=null){
return conn;
}
//如果当前数量小于最大的连接数量就创建新的连接
if(count.get() < this.mysqlpollConfig.getMaxTotal()){
Connection mysqlConn = createCon();
this.activeMysqlConnQueue.offer(mysqlConn);
return mysqlConn;
}
if(System.currentTimeMillis()-startTime>this.mysqlpollConfig.getMaxWaitTime()){
throw new MysqlConnException("连接超时!");
}
}
}
//归还连接
@Override
public void replease(Connection conn) {
//删除活动队列当中的连接
if(this.activeMysqlConnQueue.remove(conn)){
//把这个连接放入空闲连接当中
this.mysqlConnQueue.offer(conn);
}
}
//获取mysql连接信息
public Connection createCon(){
String url = this.mysqlpollConfig.getUrl();
String userName = this.mysqlpollConfig.getUserName();
String password = this.mysqlpollConfig.getPassword();
Connection mysqlConn = null;
try {
mysqlConn = DriverManager.getConnection(url, userName, password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
log.info("初始化了一个数据库连接,{ip:"+this.mysqlpollConfig.getIp()+" port:"+this.mysqlpollConfig.getPort()+" databaseNameL:"+this.mysqlpollConfig.getDatabaseName()+"}");
return mysqlConn;
}
//关闭连接
@Override
public void closeConn() {
closeBaseConn();
closeActiveConn();
}
//关闭空闲连接
public void closeBaseConn(){
Connection poll = this.mysqlConnQueue.poll();
if(poll!=null){
try {
poll.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
try {
if(poll.isClosed()){
this.mysqlConnQueue.offer(poll);
}
} catch (SQLException e) {
e.printStackTrace();
}
}finally {
closeBaseConn();
}
}
}
//关闭活动连接
public void closeActiveConn(){
Connection poll = this.activeMysqlConnQueue.poll();
if(poll!=null){
try {
poll.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
try {
if(!poll.isClosed()){
this.activeMysqlConnQueue.offer(poll);
}
} catch (SQLException e) {
e.printStackTrace();
}
}finally {
closeActiveConn();
}
}
}
}
测试 这里有redis和mysql的测试 因为当时还写了redis的连接池 删掉redis的测试就可以了
import com.poll.config.MysqlPollConfig;
import com.poll.config.RedisPollConfig;
import com.poll.poll.MysqlPoll;
import com.poll.poll.RedisPoll;
import redis.clients.jedis.Jedis;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.UUID;
/**
* @author : 王龄凯
* @date : 2021/5/21 13:47
**/
public class Mysql {
public static void main(String[] args) throws SQLException {
MysqlPollConfig mysqlPollConfig = new MysqlPollConfig();
mysqlPollConfig.setIp(UUID.randomUUID().toString());
mysqlPollConfig.setIp("127.0.0.1");
mysqlPollConfig.setPort(3306);
mysqlPollConfig.setDatabaseName("etl");
mysqlPollConfig.setUserName("root");
mysqlPollConfig.setPassword("root");
mysqlPollConfig.setParam("serverTimezone=UTC&characterEncoding=utf-8");
mysqlPollConfig.setDriverName("com.mysql.cj.jdbc.Driver");
mysqlPollConfig.setInitTotal(5);
mysqlPollConfig.setMaxTotal(15);
mysqlPollConfig.setMaxWaitTime(10);
BasePoll<Connection> mysqlConnon = new MysqlPoll(mysqlPollConfig);
mysqlConnon.init();
for (int i = 0; i < 5; i++) {
Connection conn = mysqlConnon.getConn();
System.out.println(conn);
mysqlConnon.replease(conn);
}
mysqlConnon.closeConn();
RedisPollConfig redisPollConfig = new RedisPollConfig();
redisPollConfig.setIp(UUID.randomUUID().toString());
redisPollConfig.setIp("127.0.0.1");
redisPollConfig.setPort(3306);
redisPollConfig.setInitTotal(5);
redisPollConfig.setMaxTotal(15);
redisPollConfig.setMaxWaitTime(10);
BasePoll<Jedis> redispoll = new RedisPoll(redisPollConfig);
redispoll.init();
for (int i = 0; i < 5; i++) {
Jedis jedis = redispoll.getConn();
System.out.println(jedis);
redispoll.replease(jedis);
}
redispoll.closeConn();
}
}
人傻了把pool写成了poll 大家介意的话自己修改一下
自己总结一些东西 希望对大家有帮助