JDBC_续_自定义数据连接池

JDBC高级续

自定义数据库连接池

1.DataSource 接口概述
 javax.sql.DataSource 接口:数据源(数据库连接池)。Java 官方提供的数据库连接池规范(接口)
     
  如果想完成数据库连接池技术,就必须实现 DataSource 接口
   
  核心功能:获取数据库连接对象:Connection getConnection();   
2.自定义数据库连接池
1 定义一个类,实现 DataSource 接口。
2 定义一个容器,用于保存多个 Connection 连接对象。
3 定义静态代码块,通过 JDBC 工具类获取 10 个连接保存到容器中。
4 重写 getConnection 方法,从容器中获取一个连接并返回。
5 定义 getSize 方法,用于获取容器的大小并返回。
  • ​ 例如1

     //1.定义一个类,实现 DataSource 接口
    public class MyDataSource implements DataSource {
       //2.准备一个容器。用于保存多个数据库连接对象
        private static List<Connection> pool = Collections.synchronizedList(new ArrayList<>());
        //2.定义静态代码块,获取多个连接对象保存到容器中
        static{
            for(int i = 1; i <= 10; i++) {
                //通过工具类获取连接对象
                Connection con = JDBCUtils.getConnection();
                pool.add(con);
            }
        }
       //4.提供一个获取连接池大小的方法
        public int getSize() {
            return pool.size();
        } 
        
        ...}
    

    案例2

    //1.定义一个类实现 DataSource接口
    public class Demo001 implements DataSource {
        //2.准备一个容器。用于保存多个数据库连接对象
        private List<Connection> pool;
       //3/
        public Demo001() {
            pool = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                Connection conn = JDBCUtils.getConnection();
                pool.add(conn);
            }
        }
    
        //4.提供一个获取连接池大小的方法
        public int getSize() {
            return pool.size();
        }
    

3.自定义数据库连接池的测试 测试功能是否完成

归还 数据库的连接

1.继承方式

 继承方式归还数据库连接的思想
     通过打印连接对象,发现 DriverManager 获取的连接实现类是 JDBC4Connection
      那我们就可以自定义一个类,继承 JDBC4Connection 这个类,重写 close() 方法,完成连接对象的归还

继承方式的实现步骤

    //1.定义一个类,继承JDBC4Connection
public class MyConnection1 extends JDBC4Connection{//1.定义一个类,继承JDBC4Connection
    //2.定义Connection连接对象和容器对象的成员变量
    private Connection con;
    private List<Connection> pool;

    //3.通过有参构造方法为成员变量赋值
    public MyConnection1(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url,Connection con,List<Connection> pool) throws SQLException {
        super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url);
        this.con = con;
        this.pool = pool;
    }

    //4.重写close方法,完成归还连接
    @Override
    public void close() throws SQLException {
        pool.add(con);
    }
}

继承方式归还数据库连接存在的问题

    通过查看 JDBC 工具类获取连接的方法发现:我们虽然自定义了一个子类,完成了归还连接的操作。
        但是 DriverManager 获取的还是 JDBC4Connection 这个对象,并不是我们的子类对象,而我们又不能整体去修改驱动包中类的功能,所继承这种方式行不通!

2.装饰者模式

装饰设计模式归还数据库连接的思想

我们可以自定义一个类,实现 Connection 接口。这样就具备了和 JDBC4Connection 相同的行为了
     重写 close() 方法,完成连接的归还。其余的功能还调用 mysql 驱动包实现类原有的方法即可

实现步骤

   //1.定义一个类,实现Connection接口
public class MyConnection2 implements Connection{

    //2.定义连接对象和连接池容器对象的成员变量
    private Connection con;
    private List<Connection> pool;

    //3.通过有参构造方法为成员变量赋值
    public MyConnection2(Connection con,List<Connection> pool) {
        this.con = con;
        this.pool = pool;
    }

    //4.重写close方法,完成归还连接
    @Override
    public void close() throws SQLException {
        pool.add(con);
    }

    //5.剩余方法,还是调用原有的连接对象中的功能即可
    @Override
    public Statement createStatement() throws SQLException {
        return con.createStatement();
    }
    ...}

​ 装饰设计模式归还数据库连接存在的问题

实现 Connection 接口后,有大量的方法需要在自定义类中进行重写

3.适配器设计模式

适配器设计模式归还数据库连接的思想

我们可以提供一个适配器类,实现 Connection 接口,将所有方法进行实现(除了close方法)
    自定义连接类只需要继承这个适配器类,重写需要改进的 close() 方法即可

实现步骤1 定义一个适配器类

    //1.定义一个适配器类。实现Connection接口
public abstract class MyAdapter implements Connection {

    //2.定义连接对象的成员变量
    private Connection con;

    //3.通过有参构造为变量赋值
    public MyAdapter(Connection con) {
        this.con = con;
    }


    //4.重写所有的抽象方法(除了close)
    @Override
    public Statement createStatement() throws SQLException {
        return con.createStatement();
    }
    ...其余方法

实现步骤2 定义一个类继承适配器类

    //1.定义一个类,继承适配器类
public class MyConnection3 extends MyAdapter {

    //2.定义连接对象和连接池容器对象的成员变量
    private Connection con;
    private List<Connection> pool;

    //3.通过有参构造为变量赋值
    public MyConnection3(Connection con,List<Connection> pool) {
        super(con);
        this.con = con;
        this.pool = pool;
    }

    //4.重写close方法,完成归还连接
    @Override
    public void close() {
        pool.add(con);
    }
}

适配器设计模式归还数据库连接存在的问题

自定义连接类虽然很简洁了,但适配器类还是我们自己编写的,也比较的麻烦

4.动态代理方式

动态代理:在不改变目标对象方法的情况下对方法进行增强
     组成
    被代理对象:真实的对象
    代理对象:内存中的一个对象	
 
    要求
代理对象必须和被代理对象实现相同的接口  
    
     实现
Proxy.newProxyInstance()

案例

//先定义一个接口
public interface StudentInterface {
    void eat(String name);
    void study();
}
//再定义一个类实现接口
public class Student implements StudentInterface{
    public void eat(String name) {
        System.out.println("学生吃" + name);
    }

    public void study() {
        System.out.println("在家自学");
    }
}

/*要求:在不改动Student类中任何的代码的前提下,通过study方法输出一句话:来xx学习
            类加载器:和被代理对象使用相同的类加载器
            接口类型Class数组:和被代理对象使用相同接口
            代理规则:完成代理增强的功能*/
public class Test {
    public static void main(String[] args) {
        Student stu = new Student();
        StudentInterface proxyStu = (StudentInterface) Proxy.newProxyInstance(stu.getClass().getClassLoader(), new Class[]{StudentInterface.class}, new InvocationHandler() {
            /*
                执行Student类中所有的方法都会经过invoke方法
                对method方法进行判断
                    如果是study,则对其增强
                    如果不是,还调用学生对象原有的功能即可
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if(method.getName().equals("study")) {
                    System.out.println("来黑马学习");
                    return null;
                }else {
                    return method.invoke(stu,args);
                }
            }
        });

        proxyStu.eat("米饭");
        proxyStu.study();
    }
}    

动态代理模式

作用: 在不改变原有类的情况下,增强原有类的功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值