自定义连接池:方法增强
自定义连接池中存在严重问题,用户调用getConnection()获得连接后,必须使用backConnection进行连接的归还,如果用户希望调用conn.close()方法将连接真正的释放,连接池中将出现无连接可用。
此时我们希望,当用户调用close()方法时可以将连接归还连接池。
方法增强总结
1.继承,子类继承父类,将父类的方法进行复写,从而进行增强。
使用前提:必须有父类,且存在继承关系。
2.使用装饰者模式,此设计模式专门用于增强方法。
使用前提:必须有接口
缺点:需要将接口的所有方法实现
3.动态代理:在运行时动态的创建代理类,完成增强操作。与装饰者相似使用前提:必须有接口
4.字节码增强,运行时创建目标类子类,从而进行增强,常见第三方框架:cglib、javassist等
装饰者设计模式
设计模式:专门为解决某一类问题,而编写的固定格式的代码。
装饰者固定结构:接口A,已知实现类C,需要装饰者创建代理类B
1.创建类B,并实现接口A
2.提供类B的构造方法,参数类型为A,用于接收A接口的其他实现类(C)
3.给类B添加类型A成员变量,用于存放A接口的其他实现类
4.增强需要的方法
5.实现不需要增强的方法,方法体重调用成员变量存放的其他实现类对应的方法
//1.创建类Myconnection并实现Connection借口
public class MyConnection implements Connection{
//3.定义一个变量
private Connection conn;
private LinkedList
pool;
//2.提供类MyConnection的构造方法
//多态实现构造方法里面参数是用接口类型
public MyConnection(Connection conn,LinkedList
pool) {
// TODO Auto-generated constructor stub
this.conn=conn;
this.pool=pool;
}
//4.书写需要增强的方法
@Override
public void close() throws SQLException {
// TODO Auto-generated method stub
pool.add(conn);
}
/**
* 此方法必须覆盖否则会出现空指针异常
*/
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
// TODO Auto-generated method stub
return conn.prepareStatement(sql);
}
....
/**
* 使用改造过的connection的方法
* @author fanhangqi
*
*/
public class MyDataSource1 implements DataSource{
//1.创建一个容器存储Connection对象
private static LinkedList
pool=new LinkedList
();
//2.创建一个五个连接加入到容器中
static{
for(int i=0;i<5;i++){
Connection conn= JDBCUtils_V3.getConnection();
MyConnection myconn=new MyConnection(conn, pool);
//放入池子中的Connection的对象已经经过改造
pool.add(myconn);
}
}
/**
* 重写获取链接的方法
*/
@Override
public Connection getConnection() throws SQLException {
Connection conn=null;
//3.使用连接词前先进行判断连接池是否为空
if(pool.size()==0){
//4.如果池子里面没有需要添加一下
for(int i=0;i<5;i++){
conn= JDBCUtils_V3.getConnection();
MyConnection myconn=new MyConnection(conn, pool);
//放入池子中的Connection的对象已经经过改造
pool.add(myconn);
}
}
//5.从池子里面获取一个链接对象
conn=pool.remove(0);
return conn;
}
/**
* 使用改造过的连接池方法添加用户
*/
@Test
public void testAddUser1() {
Connection conn = null;
PreparedStatement pstmt = null;
// 1.创建自定义连接池对象
DataSource dataSource = new MyDataSource1();
try {
// 2.从池子中获取连接
conn = dataSource.getConnection();
String sql = "insert into tbl_user values(null,?,?)";
pstmt = conn.prepareStatement(sql);
//3.必须从自定义的Connection中重写perparStatement方法
pstmt.setString(1, "吕");
pstmt.setString(2, "布");
int rows = pstmt.executeUpdate();
if (rows > 0) {
System.out.println("添加成功!");
} else {
System.out.println("添加失败!");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JDBCUtils_V3.release(conn, pstmt, null);
}
}