jdbc连接池简单封装

主要实现方法是:
使用一个容器(LinkedList),初始化的时候设定好连接数,生成Connection对象放在容器中
以后每次获取连接的时候都从容器中获取,但是这样有一个问题,当我们关闭连接的时候调用
Connection的close()方法的时候会直接将Connection关闭而不是重新放到容器中……
在这里使用的是代理,真正使用的是通过代理生成的一个存放在内存中的类,在这个类拦截了close()方法,在close()方法中将连接重新放回容器中......


数据库连接池类

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;

public class MyDataSource{

private static String url = "jdbc:mysql://localhost:3306/jdbc";
private static String user = "root";
private static String password = "";

//初始化连接个数
private static int initCount = 1;

//最大连接个数
private static int maxCount = 1;

//当前连接个数
int currentCount = 0;

/**
* 使用linkedList是由于频繁的对容器进行增加和删除操作,相比ArrayList快
*/
LinkedList<Connection> connectionsPool = new LinkedList<Connection>();

/**
* 初始化数据连接池中的连接个数
* @throws ClassNotFoundException
*/
public MyDataSource() throws ClassNotFoundException {
Class.forName("com.mysql.jdbc.Driver");
try {
for (int i = 0; i < initCount; i++) {
this.connectionsPool.addLast(this.createConnection());
this.currentCount++;
}
} catch (SQLException e) {
throw new ExceptionInInitializerError(e);
}
}

/**
* 从数据连接池中获取连接
* @return
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
synchronized (connectionsPool) {
if (this.connectionsPool.size() > 0)
return this.connectionsPool.removeFirst();

if (this.currentCount < maxCount) {
this.currentCount++;
return this.createConnection();
}

throw new SQLException("��û��t��");
}
}

/**
* 连接关闭后返回连接池中
* @param conn
*/
public void free(Connection conn) {
this.connectionsPool.addLast(conn);
}

/**
* 创建连接,使用代理模式
* 实际上生成的不是java.sql.Connection
* proxy.bind(realConn);返回的是经过封装后的Connection
* 在其调用close()方法的时候拦截然后在close()方法中将连接放回连接池而不是直接关闭
* @return
* @throws SQLException
*/
private Connection createConnection() throws SQLException {
Connection realConn = DriverManager.getConnection(url, user, password);
MyConnectionHandler proxy = new MyConnectionHandler(this);
return proxy.bind(realConn);
}

public static void main(String[] args) throws Exception {
MyDataSource mds = new MyDataSource();
for(int i=0; i<10; i++) {
Connection conn = mds.getConnection();
System.out.println(conn);
conn.close();
}
}
}




代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

class MyConnectionHandler implements InvocationHandler {

//普通的jdbc Connection
private Connection realConnection;

//通过代理在内存中生成的类
private Connection warpedConnection;

private MyDataSource dataSource;

//每个连接最多使用次数
private int maxUseCount = 5;

//连接当前使用次数
private int currentUserCount = 0;

MyConnectionHandler(MyDataSource dataSource) {
this.dataSource = dataSource;
}

/**
* 使用Proxy代理生成一个类
* 注意,生成的类不是我们以文本格式存在
* 而是存在内存中的
* @param realConn
* @return
*/
Connection bind(Connection realConn) {
this.realConnection = realConn;
/**
* Proxy.newProxyInstance(loader, interfaces, h)
* 其中loader是类加载器
* interfaces是要实现的接口,这里使用的是java.sql.Connection
* h是InvocationHandler,调用方法后交给哪个对象处理
*/
this.warpedConnection = (Connection) Proxy.newProxyInstance(this
.getClass().getClassLoader(), new Class[] { Connection.class },
this);
return warpedConnection;
}

/**
* 每个代码实例都具有一个关联的调用处理程序。
* 对代理实例调用方法时,
* 将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//拦截close()方法,重写里面的方法
if ("close".equals(method.getName())) {
this.currentUserCount++;
if (this.currentUserCount < this.maxUseCount)
this.dataSource.connectionsPool.addLast(this.warpedConnection);
else {
this.realConnection.close();
this.dataSource.currentCount--;
}
}
//其他方法调用普通的jdbc Connection处理
return method.invoke(this.realConnection, args);
}

}



上述代码只是简单进行封装,主要是让大家了解一下数据库连接池的实现方式以及了解一下代理的实现,对以后学习Hibernate以及Spring的AOP有较大帮助
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于JDBC数据库连接池封装的问题。一般来说,数据库连接池是一种可以重复使用的数据库连接资源集合,提高了数据库的访问效率,尤其是在高并发环境下。下面是一个简单JDBC连接池封装代码: ```java public class ConnectionPool { private static ConnectionPool instance = null; private Vector<Connection> connectionPool = new Vector<Connection>(); private String url = "jdbc:mysql://localhost:3306/test"; private String user = "root"; private String password = "root"; private int poolSize = 10; //初始化连接池,创建连接 private ConnectionPool() { for (int i = 0; i < poolSize; i++) { try { Class.forName("com.mysql.jdbc.Driver"); Connection connection = DriverManager.getConnection(url, user, password); connectionPool.add(connection); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } } //获取连接池实例 public static synchronized ConnectionPool getInstance() { if (instance == null) { instance = new ConnectionPool(); } return instance; } //获取连接 public synchronized Connection getConnection() { Connection connection = null; if (connectionPool.size() > 0) { connection = connectionPool.get(0); connectionPool.remove(connection); } return connection; } //释放连接 public synchronized void releaseConnection(Connection connection) { connectionPool.add(connection); } } ``` 在上述代码中,我们使用了一个Vector来存储连接,然后通过getInstance()方法获取连接池实例,在需要使用连接时,调用getConnection()方法获取连接,使用完毕后,调用releaseConnection()方法释放连接,从而实现了JDBC连接池封装
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值