package com.zjw.mymysql.dao;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class NormalLinkPool {
public static Connection getConnection() {
return Pool.getConnection();
}
public static void destory(Connection connection) {
Pool.destoryConnection(connection);
}
//池,管理连接的连接池
private static class Pool {
private static String DRIVER;
private static String USERNAME;
private static String PASSWORD;
private static String URL;
private static int INIT; //初始化连接个数,先创建这么多个
private static int MAXSIZE; //最大连接数
private static long MAXWAIT; //最大等待数
private static String VALIDATIONQUERY; //检查管道是否能用的sql语句
private static List<ConnectionEntity> pools = new ArrayList<>();
static {
loadProperties();
// System.out.println(URL);
//读取属性文件获得配置
for (int i = 0; i <= INIT; i++) {
pools.add(buildConnection());
}
}
public static void loadProperties() {
try {
//加载文件位置
String path = URLDecoder.decode(NormalLinkPool.class.getResource("/driver.properties").getPath(), "utf-8");
//根据文件位置加载配置文件内容
Properties prop = new Properties();
prop.load(new FileInputStream(path));
//根据文件中key的名称获取数据并填充本类的几个属性
DRIVER = prop.getProperty("driver");
URL = prop.getProperty("url");
USERNAME = prop.getProperty("username");
PASSWORD = prop.getProperty("password");
INIT = Integer.parseInt(prop.getProperty("init"));
MAXSIZE = Integer.parseInt(prop.getProperty("maxsize"));
MAXWAIT = Long.parseLong(prop.getProperty("maxwait"));
VALIDATIONQUERY = prop.getProperty("validationQuery");
} catch (IOException e) {
e.printStackTrace();
}
}
//创建连接
private static ConnectionEntity buildConnection() {
Connection conn = null;
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
// 创建ConnectionEntity,不给isBusy属性赋值就会是默认值false,表示不是正在被使用,是空闲的
return ConnectionEntity.builder().conn(conn).build();
}
//用户获取链接的方法
public static Connection getConnection() {
//在pools里面先查询是否有空闲的链接,如果有就直接给用户
for (ConnectionEntity connectionEntity : pools) {
if (!connectionEntity.isBusy()) {
//用户准备使用这个链接了,先把这个链接设置成忙碌状态
connectionEntity.setBusy(true);
return connectionEntity.getConn();
}
}
//如果在上一步中发现没有空闲连接,就用当前的链接个数和最大链接个数比较
//如果当前连接小于最大连接数,就创建一个新的链接发送给用户,并把链接设置为忙并存放在pool中
if (pools.size() < MAXSIZE) {
ConnectionEntity conn = buildConnection();
conn.setBusy(true);
pools.add(conn);
return conn.getConn();
}
//如果没有空闲链接,并且连接数达到上限,则用户等待
try {
//用户等待(线程睡眠)
Thread.sleep(MAXWAIT);
} catch (InterruptedException e) {
e.printStackTrace();
}
//等完以后,再次尝试获取链接
return getConnection();
}
//用户释放连接的方法
public static void destoryConnection(Connection connection) {
//先检查用户链接是否良好
try {
PreparedStatement pstat = connection.prepareStatement(VALIDATIONQUERY);
pstat.executeQuery();
//如果没有出现异常就继续下面的工作 将用户归还的链接设置为空闲
for (ConnectionEntity connectionEntity : pools) {
if (connectionEntity.getConn() == connection) {
connectionEntity.setBusy(false);
break;
}
}
} catch (SQLException e) {
//出现异常移除链接
for (ConnectionEntity connectionEntity : pools) {
if (connectionEntity.getConn() == connection) {
pools.remove(connectionEntity);
break;
}
}
}
}
}
//测试
public static void main(String[] args) {
for (int i = 0; i < 16; i++) {
Connection con = NormalLinkPool.getConnection();
System.out.println(con);
if (i == 14) {
NormalLinkPool.destory(con);
}
}
}
}
JDBC连接池代码
最新推荐文章于 2023-12-05 16:02:33 发布