当前位置:首页 > 话题广场 > 攻略专题 > 游戏问答

手写数据库连接池你还不会?废话少说,直接上代码

前言

数据库连接池负责分配、管理和断开数据库连接,使应用程序能够重用现有数据库连接,而不是重新建立。断开空闲时间超过最大空闲时间的数据库连接,以防止数据库连接未断开而导致的数据库连接丢失。

这项技术能明显提高对数据库操作的性能。

废话少说,直接上代码!

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

上一篇

如何处理偶发的Bug看这里!20%的业务代码的Spring声明式事务,可能都没处理正确

下一篇

.com达康是什么梗?终于找到答案了不谈尺度只看颜值,达康书记到底靠什么完爆小鲜肉圈粉无数

.net如何连接数据库连接池看这里!Java后端精选技术:Druid数据库连接池就是这么简单

.net如何连接数据库连接池看这里!Java后端精选技术:Druid数据库连接池就是这么简单

.net如何连接数据库连接池相关介绍,前言 本章主要介绍Druid数据库连接池。为什么要学Druid数据库连接池?嗯? 我的知识储备数据库连接池有C3P0、DBCP两种,现在好像还不够用~当时学习C3P0的时候觉得这个数据库连接池很强大。...

.net如何连接数据库连接池?我来告诉你答案Java后端精选技术:Druid数据库连接池就是这么简单

.net如何连接数据库连接池?我来告诉你答案Java后端精选技术:Druid数据库连接池就是这么简单

.net如何连接数据库连接池相关介绍,前言 本章主要介绍Druid数据库连接池。为什么要学Druid数据库连接池?嗯? 我的知识储备数据库连接池有C3P0、DBCP两种,现在好像还不够用~当时学习C3P0的时候觉得这个数据库连接池很强大。...

关于.net如何连接数据库连接池,你需要知道这些手写数据库连接池你还不会?废话少说,直接上代码

关于.net如何连接数据库连接池,你需要知道这些手写数据库连接池你还不会?废话少说,直接上代码

.net如何连接数据库连接池相关介绍,前言 数据库连接池负责分配、管理和断开数据库连接,使应用程序能够重用现有数据库连接,而不是重新建立。断开空闲时间超过最大空闲时间的数据库连接,以防止数据库连接未断开而导致的数据库连接丢失。 这项技术能...

关于.net如何连接数据库连接池,你需要知道这些Java后端精选技术:Druid数据库连接池就是这么简单

关于.net如何连接数据库连接池,你需要知道这些Java后端精选技术:Druid数据库连接池就是这么简单

.net如何连接数据库连接池相关介绍,前言 本章主要介绍Druid数据库连接池。为什么要学Druid数据库连接池?嗯? 我的知识储备数据库连接池有C3P0、DBCP两种,现在好像还不够用~当时学习C3P0的时候觉得这个数据库连接池很强大。...

.net如何连接数据库连接池?终于找到答案了连接池:别让连接池帮了倒忙

.net如何连接数据库连接池?终于找到答案了连接池:别让连接池帮了倒忙

.net如何连接数据库连接池相关介绍,今天,我要讲另一个重要的汇集技术:连接池。 我先说一下连接池的结构。 连接池一般对外提供获得连接、归还连接的接口给客户端使用,并暴露最小空闲连接数、最大连接数等可配置参数,在内部则实现连接建立、连接心...

.net如何连接数据库连接池?总结很全面速看!手写数据库连接池你还不会?废话少说,直接上代码

.net如何连接数据库连接池?总结很全面速看!手写数据库连接池你还不会?废话少说,直接上代码

.net如何连接数据库连接池相关介绍,前言 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连...

.net如何连接数据库连接池看这里!手写数据库连接池你还不会?废话少说,直接上代码

.net如何连接数据库连接池看这里!手写数据库连接池你还不会?废话少说,直接上代码

.net如何连接数据库连接池相关介绍,前言 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连...

.net如何连接数据库连接池?终于找到答案了还不懂数据库连接池的原理?看这篇文章啊

.net如何连接数据库连接池?终于找到答案了还不懂数据库连接池的原理?看这篇文章啊

.net如何连接数据库连接池相关介绍,作者:邓格 原文: 这次我们对数据库连接池的技术出现过程和原理,以及当前最受欢迎的开源数据库连接池jar数据包采取技术进化的方式。 一.早期我们怎么进行数据库操作 1.原理:一般来说,java应用程序...