Hi i,m JinXiang
⭐ 前言 ⭐
本篇文章主要介绍自定义一个简单的JDBC连接池实现方法以及部分理论知识
🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁
🍉博主收将持续更新学习记录获,友友们有任何问题可以在评论区留言
目录
⭐什么是连接池?
连接池(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;
@Override
public Connection getConnection() throws SQLException {
return daDetConnection(username,password);
}
@Override
public 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);
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public 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)
@Override
public void close() throws SQLException {
//把连接从工作连接池放回空闲连接池
if (myDataSoures.getIdlePool().size() < myDataSoures.getMaxActive()){
myDataSoures.getWorkPool().remove(this);
myDataSoures.getIdlePool().addLast(this);
}
}
@Override
public boolean isClosed() throws SQLException {
return false;
}
@Override
public Statement createStatement() throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return connection.prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return connection.prepareCall(sql);
}
@Override
public String nativeSQL(String sql) throws SQLException {
return connection.nativeSQL(sql);
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
}
@Override
public boolean getAutoCommit() throws SQLException {
return connection.getAutoCommit();
}
@Override
public void commit() throws SQLException {
}
@Override
public void rollback() throws SQLException {
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return connection.getMetaData();
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
}
@Override
public boolean isReadOnly() throws SQLException {
return connection.isReadOnly();
}
@Override
public void setCatalog(String catalog) throws SQLException {
}
@Override
public String getCatalog() throws SQLException {
return null;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
}
@Override
public int getTransactionIsolation() throws SQLException {
return 0;
}
@Override
public SQLWarning getWarnings() throws SQLException {
return null;
}
@Override
public void clearWarnings() throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return null;
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
}
@Override
public void setHoldability(int holdability) throws SQLException {
}
@Override
public int getHoldability() throws SQLException {
return 0;
}
@Override
public Savepoint setSavepoint() throws SQLException {
return null;
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
return null;
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return null;
}
@Override
public Clob createClob() throws SQLException {
return null;
}
@Override
public Blob createBlob() throws SQLException {
return null;
}
@Override
public NClob createNClob() throws SQLException {
return null;
}
@Override
public SQLXML createSQLXML() throws SQLException {
return null;
}
@Override
public boolean isValid(int timeout) throws SQLException {
return false;
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
}
@Override
public String getClientInfo(String name) throws SQLException {
return null;
}
@Override
public Properties getClientInfo() throws SQLException {
return null;
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return null;
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return null;
}
@Override
public void setSchema(String schema) throws SQLException {
}
@Override
public String getSchema() throws SQLException {
return null;
}
@Override
public void abort(Executor executor) throws SQLException {
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
}
@Override
public int getNetworkTimeout() throws SQLException {
return 0;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public 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方法
@Override
public 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.Test
public 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!!如有问题,欢迎评论区批评指正😁