数据库链接池
数据库链接池的简介
数据库链接池是什么
数据库链接-池,顾名思义就是存放数据库链接的池子。
数据库链接池的作用
存放数据库链接供人获取调用
数据库链接池的好处
不需要每个链接都需要自己创建,只在刚开始初始化的时候创建一定数量的链接,节省了资源时间,效率高,现拿现用。
模拟数据库链接池
package com.jyh.jdbc.pool;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.jyh.jdbc.JdbcUtil;
public class SimpleConnectionPool {
private static List<Connection> cl = Collections.synchronizedList(new ArrayList<Connection>());
static{
for(int i = 0;i < 10; i ++){
//初始化连接池向连接池中添加一定数量的链接
cl.add(JdbcUtil.getConnection());//该链接都是从已写好的jdbc工具类中获取的
}
}
public static Connection getConnection(){
if(cl.size() <= 0){
///如果链接池中没有链接了则可以再创建若干个链接放入池中
for(int i = 0;i < 10; i ++){
cl.add(JdbcUtil.getConnection());
}
}
//返回第一个链接并从链接池中删除
return cl.remove(0);
}
public static void release(Connection conn){
cl.add(conn);
}
public static void main(String[] args) {
//从链接池中获取链接
Connection conn = SimpleConnectionPool.getConnection();
//一系列操作
System.out.println(conn.getClass().getName());
//将链接放回链接池,这里不能调用.close()方法,而是自己定义了一个方法
SimpleConnectionPool.release(conn);
}
}
需要解决的问题
发现的问题
从池中获取一个链接后,用户用完自觉的调用conn.close()方法。应该达到的效果:不要关闭,而应该还回池中,而com.mysql.jdbc.Connection.close():只会关闭
解决方法
1. 静态代理还是装饰设计模式?
我们需要将该方法变成返还到池中,然后我们立即想到了可以重写该方法啊,等我们准备继承该类的时候发现,无法继承,所以这个方法不行。
我们要用这个类是这类里面有我们需要的方法,所以我们自己建一个跟它一样的类不就行了么,继承同一个接口,然后方法实现也编写得一样,只把我们需要改变的方法改成我们需要的样子。想要方法实现是一样的,那么直接调用以前的不就行了了,所以需要在新建的类中new一个com.mysql.jdbc.Connection实例,不需要改变的方法直接调用实例的方法,需要改变的方法自己重写。然后又想到了,如果直接在新类中new一个com.mysql.jdbc.Connection实例就定死了,万一要换数据库呢,别的数据库可不是这个类实现java.sql.Connection接口的。所以不能定死,要从外面传过来。于是我们可以在新的类里面定义一个java.sql.Connection类型的变量,反正无论什么数据库驱动都是要实现这个类的,该变量在新类初始化的时候由外面传一个数据库驱动实例进来,通过构造函数进行赋值初始化,这样就好了吧。但是,不要忘了我们要改写的方法是什么样的—将close()方法改写成放入链接池,所以链接池的实例不能缺少,于是再定义一个链接池变量,也在新类初始化的时候赋值初始化。代码如下:
package com.jyh.jdbc.pool;
import java.util.List;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
public class MyConnection implements Connection {
private Connection conn;//需要初始化的数据库驱动
private List<Connection> cl;//需要初始化的链接池
public MyConnection(Connection conn, List<Connection> cl) {
this.conn = conn;
this.cl = cl;
}
//需要改写的close方法
public void close() throws SQLException {
System.out.println("这里是MyConnection的close方法");
cl.add(conn);
}
//其它不需要改写的方法直接调用传过来的实例里面的方法即可
public <T> T unwrap(Class<T> iface) throws SQLException {
return conn.unwrap(iface);
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return conn.isWrapperFor(iface);
}
public Statement createStatement() throws SQLException {
return conn.createStatement();
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
return conn.prepareStatement(sql);
}
public CallableStatement prepareCall(String sql) throws SQLException {
return conn.prepareCall(sql);
}
public String nativeSQL(String sql) throws SQLException {
return conn.nativeSQL(sql);
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
conn.setAutoCommit(autoCommit);
}
public boolean getAutoCommit() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public void commit() throws SQLException {
// TODO Auto-generated method stub
}
public void rollback() throws SQLException {
// TODO Auto-generated method stub
}
public boolean isClosed() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public DatabaseMetaData getMetaData() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public void setReadOnly(boolean readOnly) throws SQLException {
// TODO Auto-generated method stub
}
public boolean isReadOnly() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public void setCatalog(String catalog) throws SQLException {
// TODO Auto-generated method stub
}
public String getCatalog() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public void setTransactionIsolation(int level) throws SQLException {
// TODO Auto-generated method stub
}
public int getTransactionIsolation() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
public SQLWarning getWarnings() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public void clearWarnings() throws SQLException {
// TODO Auto-generated method stub
}
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public Map<String, Class<?>> getTypeMap() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
// TODO Auto-generated method stub
}
public void setHoldability(int holdability) throws SQLException {
// TODO Auto-generated method stub
}
public int getHoldability() throws SQLException {