开始尝试仿写一个数据库连接池

Posted 折花

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了开始尝试仿写一个数据库连接池相关的知识,希望对你有一定的参考价值。

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.*;
import java.util.LinkedList;
import java.util.Properties;
import java.util.logging.Logger;

/**
* 实现思路:
* 1、继承sun接口
* 2、批量保存创建Connection
* 3、实现get函数,从list中获取连结
* 4、重写Connection的Close方法,这有点难点
* TODO 学习HikariCP的优秀实现
*/
public class LittleDataSource implements DataSource{
/**
    * TODO 链表应该有进化空间
    */
   private static LinkedList<Connection> connList = new LinkedList<Connection>();
static {
InputStream propInput = LittleDataSource.class.getClassLoader().getResourceAsStream("db.properties");
Properties prop = new Properties();
try {
prop.load(propInput);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");

Class.forName(driver);
/**
            * TODO 10 => 默认连接数大小和配置连接数大小
            */
           for (int i=0;i<10;i++){
Connection conn = DriverManager.getConnection(url,username,password);
connList.add(conn);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}

/**
    *
    * 数据库连接池实现sun的接口
    * 重点是实现getConnection和Connection的Close
    * 前者从List中获取
    * 后者将关闭改为放回List
    *
    * @return
    * @throws SQLException
    */
   @Override
   public Connection getConnection() throws SQLException {
if(connList.size() > 0){
final Connection connection = connList.removeFirst();
/**
            * 这里目前使用动态代理增强字节码
            * 在运行时替换close方法,除此之外其他方法没得实现
            * TODO 使用一些字节码操纵技术换掉Proxy
            */
           return (Connection) Proxy.newProxyInstance(LittleDataSource.class.getClassLoader(), connection.getClass().getInterfaces(), new InvocationHandler() {
@Override
               public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(!method.getName().equals("close")){
method.invoke(connection,args);
}else{
connList.add(connection);
}
return null;
}
});
}
return null;
}

@Override
   public Connection getConnection(String username, String password) throws SQLException {
return null;
}
 }


以上是关于开始尝试仿写一个数据库连接池的主要内容,如果未能解决你的问题,请参考以下文章

Mysql连接池

安全地包装连接池

从零开始手写 mybatis jdbc pool 从零实现数据库连接池

从零开始手写 mybatis jdbc pool 从零实现数据库连接池

如何快速实现一个连接池?

python中的MySQL连接池?