一个简易的 MySQL 连接池实现
Mysql连接池
就是存储一堆 MySQL 连接的池子。
现在现成的 MySQL 连接池第三方jar应该有很多,但是有时候我们在项目中只是需要简单的用一下连接池去跑大量数据,比如在跑 batch 任务的时候,可能就不想去引入第三方 jar 包,于是我自己去简单了实现了一下连接池。其实连接池也很简单,就是我们提前申请好与 MySQL 的 connection 连接,然后讲这些连接放入到内存里面,这样我们的任务需要连接 MySQL 数据库的时候,就可以从我们提前申请好的连接池中去获取连接,而不用每次都去与 MySQL server 连接,如果你在短时间内与 MySQL server 频繁连接的话,可能会导致连接错误,所以我们应该避免这样的问题。
具体实现
首先我定义了一个 DataSource 类,这个类负责初始化 MySQL connection,以及将释放的 connection 存储起来。我这里使用 LinkedList 来作为存储的数据结构,因为我们会频繁的对这个线程池进行增加和删除。(一个线程来获取就要从池子里面删除一个connection,线程运行完就要将 connection 加入到池子),所以采用此结构;
下面讲一下代码的具体实现,实现一个具体的DataSource类:
DataSource类
private final String url = ""; //mysql 连接串
private final String user = ""; //用户名
private final String password = ""; //密码
private static int initCount = 10; //初始化connection个数
private static int maxCount = 20; //connection最大个数
private static int currentCount = 0;
private LinkedList<Connection> connectionPool = new LinkedList<>();
//只让包内引用,下面会定义一个JDBCUtils去获取Connection连接
protected MyDataSource() {
for(int i = 0; i < initCount; i++){
try {
this.connectionPool.addLast(this.createConnection());
this.currentCount++;
}catch (Exception e){
throw new ExceptionInInitializerError(e);
}
}
}
private Connection createConnection() throws SQLException{
return DriverManager.getConnection(this.url, this.user, this.password);
}
private Connection createConnection() throws SQLException{
return DriverManager.getConnection(this.url, this.user, this.password);
}
protected Connection getConnection() throws SQLException {
synchronized(this.connectionPool){
if(this.connectionPool.size() > 0){
this.currentCount--;
return this.connectionPool.removeFirst();
}
if(this.currentCount < this.maxCount){
this.createConnection();
this.currentCount++;
}
throw new SQLException("no connection");
}
}
protected void free(Connection conn){
synchronized (this.connectionPool){
this.connectionPool.addLast(conn);
this.currentCount++;
}
}
JDBCUtils具体实现类
在DataSource类的同包内定义该类,对外提供获取connection连接和释放Connection连接的工具类。
具体实现如下:
private static MyDataSource dataSource = null;
private final static String driver = "";//jdbc driver name
static {
try {
Class.forName(driver);
dataSource = new MyDataSource();
}catch (ClassNotFoundException e){
throw new ExceptionInInitializerError(e);
}
}
//对外提供的获取连接的方法
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//对外提供的释放连接的方法
public static void free(ResultSet rs, Statement st, Connection conn) throws SQLException {
if(rs != null){
rs.close();
}
if(st != null){
st.close();
}
dataSource.free(conn);
}
总结
自己去实现一个连接池类,方便自己去理解连接池的概念;有任何问题,可以在评论区进行讨论。