前言
数据库连接池负责分配、管理和断开数据库连接,使应用程序能够重用现有数据库连接,而不是重新建立。断开空闲时间超过最大空闲时间的数据库连接,以防止数据库连接未断开而导致的数据库连接丢失。
这项技术能明显提高对数据库操作的性能。废话少说,直接上代码!
package com.;
import javax.;
import java.lang.re;
import java.lang.re;
import java.lang.re;
import java.;
/**
* 对Connection对象的代理,主要作用为拦截connection的close方法
*/
public class ConnectionProxy implements InvocationHandler {
//真实的连接
private Connection realConnection ;
//代理的连接
private Connection proxyConnection ;
//数据源
private HuwcDataSource dataSource ;
//这是一个构造器
public ConnectionProxy(Connection realConnection, HuwcDataSource dataSource) {
= realConnection;
= dataSource;
//生成代理的Connection
= (Connection) Proxy.newProxyInstance(), new Class[]{Connec}, this);
}
public Connection getRealConnection() {
return realConnection;
}
public void setRealConnection(Connection realConnection) {
= realConnection;
}
public Connection getProxyConnection() {
return proxyConnection;
}
public void setProxyConnection(Connection proxyConnection) {
= proxyConnection;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(HuwcDataSource dataSource) {
= dataSource;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = me();
//拦截连接关闭的方法,对其进行扩展处理
i("close")){
synchronized ()){
//活动连接list中remove这个ConnectionProxy
da().remove(this);
//如果空闲连接list中的数量没有达到阈值,则装入空间连接list,并notifyAll
i().size() < da()){
da().add(this);
da().notifyAll();
}else{
//否则,直接关闭这个Connection
realConnec();
}
}
}else{
return me(realConnection, args) ;
}
return null;
}
}
package com.;
import javax.;
import java.io.PrintWriter;
import java.;
import java.;
import java.u;
/**
* 给与DataSource接口中一些方法默认实现(就是不实现)
*/
public abstract class HuwcAbstractDataSource implements DataSource {
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
public PrintWriter getLogWriter() throws SQLException {
return null;
}
public void setLogWriter(PrintWriter out) throws SQLException {
}
public void setLoginTimeout(int seconds) throws SQLException {
}
public int getLoginTimeout() throws SQLException {
return 0;
}
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
package com.;
import java.;
import java.;
import java.;
import java.u;
import java.u;
public class HuwcDataSource extends HuwcAbstractDataSource {
//空闲的连接
private List<ConnectionProxy> idleConnections = new ArrayList<>();
//活动的连接
private List<ConnectionProxy> activeConnections = new ArrayList<>();
//是否为本数据源第一次获取连接标志
private boolean firstFlag = true ;
//最小的空闲连接数
private Integer minIdleConnectionsCount = 2;
//最大的空闲连接数
private Integer maxIdleConnectionsCount = 5;
//最大的活动连接数
private Integer maxActiveConnectionsCount = 10;
//获取连接的最大的等待时间(毫秒)
private Integer maxWaitToTimeOut = 30000;
private String url;
private String driver;
private String user;
private String password;
private Object monitor = new Object();
public boolean isFirstFlag() {
return firstFlag;
}
public void setFirstFlag(boolean firstFlag) {
= firstFlag;
}
public List<ConnectionProxy> getIdleConnections() {
return idleConnections;
}
public void setIdleConnections(List<ConnectionProxy> idleConnections) {
= idleConnections;
}
public List<ConnectionProxy> getActiveConnections() {
return activeConnections;
}
public void setActiveConnections(List<ConnectionProxy> activeConnections) {
= activeConnections;
}
public Integer getMaxIdleConnectionsCount() {
return maxIdleConnectionsCount;
}
public void setMaxIdleConnectionsCount(Integer maxIdleConnectionsCount) {
= maxIdleConnectionsCount;
}
public Integer getMaxActiveConnectionsCount() {
return maxActiveConnectionsCount;
}
public void setMaxActiveConnectionsCount(Integer maxActiveConnectionsCount) {
= maxActiveConnectionsCount;
}
public Integer getMaxWaitToTimeOut() {
return maxWaitToTimeOut;
}
public void setMaxWaitToTimeOut(Integer maxWaitToTimeOut) {
= maxWaitToTimeOut;
}
public Object getMonitor() {
return monitor;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
= url;
}
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
= driver;
}
public String getUser() {
return user;
}
public void setUser(String user) {
= user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
= password;
}
@Override
public Connection getConnection() throws SQLException {
return getConnection(user, password);
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return doGetConnection(username, password);
}
private Connection doGetConnection(String username, String password) throws SQLException {
while(true) {
synchronized (monitor) {
//如果是本数据源第一次获取连接,那么首先进行init操作
if(firstFlag)
init();
//首先从空闲连接list中获取
if () > 0) {
return idleConnec(0).getProxyConnection();
} else {//空闲连接list中如果没有连接的情况
//如果活动连接list的数量还没有达到阈值
if (maxActiveConnectionsCount > ac()) {
//获取一个真实的Connection,并且封装为ConnectionProxy,装入活动连接list
ConnectionProxy connectionProxy = new ConnectionProxy(url, user, password), this);
ac(connectionProxy);
return connec();
} else {
//如果活动连接list的数量已经达到了阈值
//等待超时时间,并等待被唤醒
try {
moni(maxWaitToTimeOut);
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}
}
return null ;
}
private void init() {
//首先进行锁定处理
firstFlag = false;
for(int i=0;i<minIdleConnectionsCount;i++){
try {
ConnectionProxy connectionProxy = new ConnectionProxy(url, user, password), this);
.add(connectionProxy);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
总结:
通过jdk动态代理,给Connection对象生成一个代理对象,主要目的为拦截connection的close方法,不要直接进行connection的关闭,而是在DataSource中的活动连接集合和空闲连接集合进行转换。真实的Connection依然是通过DirverManager类来创建。
原文链接:
1.《手写数据库连接池你还不会?废话少说,直接上代码》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《手写数据库连接池你还不会?废话少说,直接上代码》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/gl/2213859.html