package cn.silence_datasourece;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import cn.silence_utils.JdbcUtils;
/*
* 连接池概念:
* 1、一次性的产生多个连接对象放到连接池中
* 2、需要用连接时,就从池子中取出连接对象
* 3、用完后有放回到连接池中,这样就避免了不断创建连接,释放连接的过程,从而提高程序性能
*/
public class MyDataSource implements DataSource{
//LinkedList底层为链表增删快查询慢,ArrayList底层为数组,查询快(通过下标可直接查询),增删满
//创建一个连接池对象,由于数据库中经常做增删改操作,此处选LinkedList集合来当作连接池
private LinkedList<Connection> pool=new LinkedList<Connection>();
public MyDataSource(){
System.out.println("批量弄10个连接放入连接池");
for (int i = 0; i <10; i++) {
Connection conn = JdbcUtils.getConnection();
pool.add(conn);
}
}
@Override
public Connection getConnection() throws SQLException {
System.out.println("取出一个连接池来用");
if(pool.isEmpty()){
//如果连接池是null的话,再创建几个
for (int i = 0; i <3; i++) {
Connection conn = JdbcUtils.getConnection();
pool.add(conn);
}
}
//走到这里, 肯定有连接可以 用了
// 总是 取出 池子中 第一个连接 对象 返回给 调用者
final Connection conn = pool.removeFirst();
//产生 connection对象的代理对象 给 调用 者, 当 调用者拿到 代理的connection对象之后,再去 调用
// 任何方法时. 都会再次进入到 这里的 invocationHandler里的逻辑 ,
//创建connection的代理对象
Connection proxyConn=(Connection)Proxy.newProxyInstance(MyDataSource.class.getClassLoader(),conn.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//原有的close方法是直接将连接关闭,现在要将连接放回到连接池中,故要改进close方法
if(method.equals("close")){
addBackToPool(conn);
return null;
}
//若不是掉close方法,则走Connection的原有逻辑
return method.invoke(conn, args);
}
});
return proxyConn;
}
//将连接放回到连接池中
public void addBackToPool(Connection conn){
System.out.println("将连接放回到连接池");
pool.add(conn);
}
@Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import cn.silence_utils.JdbcUtils;
/*
* 连接池概念:
* 1、一次性的产生多个连接对象放到连接池中
* 2、需要用连接时,就从池子中取出连接对象
* 3、用完后有放回到连接池中,这样就避免了不断创建连接,释放连接的过程,从而提高程序性能
*/
public class MyDataSource implements DataSource{
//LinkedList底层为链表增删快查询慢,ArrayList底层为数组,查询快(通过下标可直接查询),增删满
//创建一个连接池对象,由于数据库中经常做增删改操作,此处选LinkedList集合来当作连接池
private LinkedList<Connection> pool=new LinkedList<Connection>();
public MyDataSource(){
System.out.println("批量弄10个连接放入连接池");
for (int i = 0; i <10; i++) {
Connection conn = JdbcUtils.getConnection();
pool.add(conn);
}
}
@Override
public Connection getConnection() throws SQLException {
System.out.println("取出一个连接池来用");
if(pool.isEmpty()){
//如果连接池是null的话,再创建几个
for (int i = 0; i <3; i++) {
Connection conn = JdbcUtils.getConnection();
pool.add(conn);
}
}
//走到这里, 肯定有连接可以 用了
// 总是 取出 池子中 第一个连接 对象 返回给 调用者
final Connection conn = pool.removeFirst();
//产生 connection对象的代理对象 给 调用 者, 当 调用者拿到 代理的connection对象之后,再去 调用
// 任何方法时. 都会再次进入到 这里的 invocationHandler里的逻辑 ,
//创建connection的代理对象
Connection proxyConn=(Connection)Proxy.newProxyInstance(MyDataSource.class.getClassLoader(),conn.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//原有的close方法是直接将连接关闭,现在要将连接放回到连接池中,故要改进close方法
if(method.equals("close")){
addBackToPool(conn);
return null;
}
//若不是掉close方法,则走Connection的原有逻辑
return method.invoke(conn, args);
}
});
return proxyConn;
}
//将连接放回到连接池中
public void addBackToPool(Connection conn){
System.out.println("将连接放回到连接池");
pool.add(conn);
}
@Override
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO Auto-generated method stub
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
// TODO Auto-generated method stub
return false;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
// TODO Auto-generated method stub
return null;
}
}