Hi i,m JinXiang
⭐ 前言 ⭐
本篇文章主要介绍自定义一个简单的JDBC连接池实现方法以及部分理论知识
🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁
🍉博主收将持续更新学习记录获,友友们有任何问题可以在评论区留言
目录
⭐什么是连接池?
🍧连接池的实现通常会包括以下几个方面:
⭐如何自定义一个连接池
🍧一、准备工作
🍧二、代码呈现
获取连接--(MyAbsyeactDateSource)
关闭连接--(MyConnection)
两个连接池状态 工作/空闲--(MyDataSoures)
🍧三、结果呈现
取用mysql连接数据库 与 自定义连接池 进行 速度比较
结果
⭐什么是连接池?
连接池(Connection Pool)是一种数据库连接管理技术,它可以对数据库连接进行复用,从而减少了重复创建和删除连接的开销,提高了系统的性能和可扩展性。
- 1、连接池在应用程序启动时创建一定数量的数据库连接,将这些连接保存在内存中,等待应用程序需要时提供给它,应用程序在使用完连接后将其放回连接池,而不是直接关闭它。当连接池中的连接数量不足时,连接池会自动创建新的连接,直到达到连接池的最大连接数为止。
- 2、连接池的主要作用是提高系统的性能和可扩展性,它可以减少数据库连接的创建和销毁次数,避免了频繁的网络交互和数据库连接的资源消耗,同时也方便了系统的升级和扩展。但连接池的缺点是会占用一定的内存和资源,并且在高并发环境中可能会出现连接池满的情况,需要合理设置连接池的参数,以便在保证系统性能的情况下,最大限度地利用连接池的资源。
🍧连接池的实现通常会包括以下几个方面:
- 1、连接池大小的管理:连接池的大小对应用程序的性能和数据库的性能都有影响。连接池大小的管理需要根据应用程序的负载情况动态调整,以提供最优的连接数量。
- 2、连接生命周期的控制:连接池管理连接的生命周期,当连接不再使用时,将其关闭并从连接池中移除。这可以释放资源,避免连接泄漏和占用过多的资源。
- 3、 连接的复用:连接池可以对数据库连接进行复用,避免每次连接数据库时都要重新创建连接,从而提高应用程序的性能和数据库的响应速度。
- 4、连接的验证:连接池通常会对连接进行验证,以确保连接可用性。如果连接不可用,连接池会移除该连接并创建新的连接。这可以避免应用程序使用已经失效的连接。
总之,连接池可以有效地管理数据库连接,提高应用程序的性能和数据库的响应速度。
⭐如何自定义一个连接池
一、准备工作
在datasoures创建三个类
二、代码呈现
获取连接--(MyAbsyeactDateSource)
//是在实现mysql实现的连接package user_defined.datasource;import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;public abstract class MyAbsyeactDateSource implements DataSource {
//=======如何得到一个连接private String url;private String username;private String password;private String driverClassName;//初始连接数private int initialSize = 10;//最大连接数private int maxActive = 30;public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getDriverClassName() {return driverClassName;}public void setDriverClassName(String driverClassName) {this.driverClassName = driverClassName;}public int getInitialSize() {return initialSize;}public void setInitialSize(int initialSize) {this.initialSize = initialSize;}public int getMaxActive() {return maxActive;}public void setMaxActive(int maxActive) {this.maxActive = maxActive;}public boolean isInitFlog() {return initFlog;}public void setInitFlog(boolean initFlog) {this.initFlog = initFlog;}//初始化值private boolean initFlog = false;@Overridepublic Connection getConnection() throws SQLException {return daDetConnection(username,password);}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return daDetConnection(username,password);}private Connection daDetConnection(String username,String password) throws SQLException {if (!initFlog){try {Class.forName(driverClassName);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}initFlog = true;}return DriverManager.getConnection(url,username,password);}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}
}
关闭连接--(MyConnection)
package user_defined.datasource;import java.sql.*;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;public class MyConnection implements Connection {
//=======如何关闭一个连接private MyDataSoures myDataSoures;private Connection connection;//构造方法public MyConnection(MyDataSoures myDataSoures, Connection connection) {this.myDataSoures = myDataSoures;this.connection = connection;}//只需要实现这两个方法(close,isClosed)@Overridepublic void close() throws SQLException {//把连接从工作连接池放回空闲连接池if (myDataSoures.getIdlePool().size() < myDataSoures.getMaxActive()){myDataSoures.getWorkPool().remove(this);myDataSoures.getIdlePool().addLast(this);}}@Overridepublic boolean isClosed() throws SQLException {return false;}@Overridepublic Statement createStatement() throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql) throws SQLException {return connection.prepareStatement(sql);}@Overridepublic CallableStatement prepareCall(String sql) throws SQLException {return connection.prepareCall(sql);}@Overridepublic String nativeSQL(String sql) throws SQLException {return connection.nativeSQL(sql);}@Overridepublic void setAutoCommit(boolean autoCommit) throws SQLException {}@Overridepublic boolean getAutoCommit() throws SQLException {return connection.getAutoCommit();}@Overridepublic void commit() throws SQLException {}@Overridepublic void rollback() throws SQLException {}@Overridepublic DatabaseMetaData getMetaData() throws SQLException {return connection.getMetaData();}@Overridepublic void setReadOnly(boolean readOnly) throws SQLException {}@Overridepublic boolean isReadOnly() throws SQLException {return connection.isReadOnly();}@Overridepublic void setCatalog(String catalog) throws SQLException {}@Overridepublic String getCatalog() throws SQLException {return null;}@Overridepublic void setTransactionIsolation(int level) throws SQLException {}@Overridepublic int getTransactionIsolation() throws SQLException {return 0;}@Overridepublic SQLWarning getWarnings() throws SQLException {return null;}@Overridepublic void clearWarnings() throws SQLException {}@Overridepublic Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {return null;}@Overridepublic CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {return null;}@Overridepublic Map<String, Class<?>> getTypeMap() throws SQLException {return null;}@Overridepublic void setTypeMap(Map<String, Class<?>> map) throws SQLException {}@Overridepublic void setHoldability(int holdability) throws SQLException {}@Overridepublic int getHoldability() throws SQLException {return 0;}@Overridepublic Savepoint setSavepoint() throws SQLException {return null;}@Overridepublic Savepoint setSavepoint(String name) throws SQLException {return null;}@Overridepublic void rollback(Savepoint savepoint) throws SQLException {}@Overridepublic void releaseSavepoint(Savepoint savepoint) throws SQLException {}@Overridepublic Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {return null;}@Overridepublic CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {return null;}@Overridepublic PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {return null;}@Overridepublic Clob createClob() throws SQLException {return null;}@Overridepublic Blob createBlob() throws SQLException {return null;}@Overridepublic NClob createNClob() throws SQLException {return null;}@Overridepublic SQLXML createSQLXML() throws SQLException {return null;}@Overridepublic boolean isValid(int timeout) throws SQLException {return false;}@Overridepublic void setClientInfo(String name, String value) throws SQLClientInfoException {}@Overridepublic void setClientInfo(Properties properties) throws SQLClientInfoException {}@Overridepublic String getClientInfo(String name) throws SQLException {return null;}@Overridepublic Properties getClientInfo() throws SQLException {return null;}@Overridepublic Array createArrayOf(String typeName, Object[] elements) throws SQLException {return null;}@Overridepublic Struct createStruct(String typeName, Object[] attributes) throws SQLException {return null;}@Overridepublic void setSchema(String schema) throws SQLException {}@Overridepublic String getSchema() throws SQLException {return null;}@Overridepublic void abort(Executor executor) throws SQLException {}@Overridepublic void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {}@Overridepublic int getNetworkTimeout() throws SQLException {return 0;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}
}
两个连接池状态 工作/空闲--(MyDataSoures)
package user_defined.datasource;import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedList;public class MyDataSoures extends MyAbsyeactDateSource {
//======两个连接池状态(工作,空闲)//工作连接池private LinkedList<MyConnection> workPool = new LinkedList<>();//空闲连接池private LinkedList<MyConnection> idlePool = new LinkedList<>();//get方法public LinkedList<MyConnection> getWorkPool() {return workPool;}public LinkedList<MyConnection> getIdlePool() {return idlePool;}public MyDataSoures(){}// TODO 从工作连接池获取到一个连接private boolean initFlag = false;//重写getconnection方法@Overridepublic Connection getConnection() throws SQLException {MyConnection connection = null;this.init();//如果空闲连接不为空就直接取if (!idlePool.isEmpty()){connection = idlePool.removeFirst();}else {//如果工作连接数小于最大连接数,就创建一个if (workPool.size() < super.getMaxActive()){connection = new MyConnection(this,super.getConnection());}}if (connection !=null){workPool.addLast(connection);}return connection;}public void init() throws SQLException {//初始化十个连接if (!initFlag) {while (idlePool.size() < super.getInitialSize()) {idlePool.add(new MyConnection(this, super.getConnection()));}initFlag = true;}}
}
三、结果呈现
取用mysql连接数据库 与 自定义连接池 进行 速度比较
package user_defined;import user_defined.datasource.MyDataSoures;import java.sql.*;public class Test {//自定义连接池public static String url = "jdbc:mysql://localhost:3306/1201moviedb?rewriteBatchedStatements=true&serverTimezone=UTC";public static String username = "root";public static String password = "root";public static String driverClassName = "com.mysql.cj.jdbc.Driver";@org.junit.Testpublic void TestDateSource() throws SQLException, ClassNotFoundException {MyDataSoures myConnection = new MyDataSoures();myConnection.setDriverClassName(driverClassName);myConnection.setUrl(url);myConnection.setUsername(username);myConnection.setPassword(password);long statr = System.currentTimeMillis(); //for (int i = 0; i < 500; i++) {Connection connection = myConnection.getConnection();connection.close();}long end = System.currentTimeMillis();System.out.println("MyDateSource 耗时:"+(end - statr)+"ms");//mysql连接数据库Class.forName("com.mysql.cj.jdbc.Driver");String url = "jdbc:mysql://localhost:3306/1201moviedb?rewriteBatchedStatements=true&serverTimezone=UTC";String username = "root";String password = "root";long statr2 = System.currentTimeMillis(); //for (int i = 0; i < 500; i++) { //执行500次Connection con2 = DriverManager.getConnection(url,username,password);con2.close();}long end2 = System.currentTimeMillis();System.out.println("传统数据库 耗时:"+(end2 - statr2)+"ms");}
}
结果:
MySql连接数据库 耗时4秒 自定义连接池 1秒
总结不易,希望uu们不要吝啬亲爱的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁