自定义数据库连接池

为什么要用数据库连接池?

mysql连接资源非常宝贵,创建连接和关闭连接花费的时间比较长,使用数据库连接池可以提高我们开发效率,用户从连接池获取连接使用用完了后,需要把连接归还给连接池,所以我们需要用LinkedList链表存储连接

编写数据库连接池
public class MyDataSource implements DataSource {

    //准备连接池集合
    private  LinkedList<Connection> conns=new LinkedList<>();


    public MyDataSource(){

        //初始化连接池  提前创建好连接,放入集合中

        try {

            //1.读取properties配置文件

            //1.1创建properties集合
            Properties properties=new Properties();

            //1.2创建字节输入流,读取properties文件的内容
            FileInputStream in = new FileInputStream("E:\\code\\code\\src\\datasource.properties");

            //1.3把InputStream中的内容保存到Properties集合中
            properties.load(in);

            //2.注册驱动
            Class.forName(properties.getProperty("jdbc.driverClassName"));


            //3.获取连接
            for(int i=0;i<Integer.valueOf(properties.getProperty("jdbc.init"));i++){

                //获取连接
                Connection conn = DriverManager.getConnection(properties.getProperty("jdbc.url"),
                        properties.getProperty("jdbc.username"), properties.getProperty("jdbc.password"));

                //把连接放入集合
                conns.add(conn);

            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("创建数据库连接池失败!");
        }


    }


    /**
     * 获取链接
     * @return
     * @throws SQLException
     */
    @Override
    public Connection getConnection() throws SQLException {

        //移除并且返回一个连接
        Connection connection = conns.removeFirst();

        return connection;
    }


    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @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;
    }
}

因为我们使用完连接后,不是关闭连接而是把链接还给linklist集合,所以我们需要重写close方法,这里用到了包装设计模式,也可以用代理设计模式

包装设计模式:
//1.编写一个类,实现Connection接口 考虑的数据库太多了
//2.继承ConnectionImpl,重写close方法
//3.装饰设计模式(包装设计模式)
// 3.1 编写一个类,实现与被增强对象相同的接口
// 3.2 定义一个变量,记住被增强对象
// 3.3 定义一个构造方法接收被增强对象
// 3.4 覆盖想覆盖的方法
// 3.5 对于不想覆盖的方法直接调用被增强对象的方法来实现

public class MyDataSource implements DataSource {

    //准备连接池集合
    private  LinkedList<Connection> conns=new LinkedList<>();


    public MyDataSource(){

        //初始化连接池  提前创建好连接,放入集合中

        try {

            //1.读取properties配置文件

            //1.1创建properties集合
            Properties properties=new Properties();

            //1.2创建字节输入流,读取properties文件的内容
            FileInputStream in = new FileInputStream("E:\\code\\code\\src\\datasource.properties");

            //1.3把InputStream中的内容保存到Properties集合中
            properties.load(in);

            //2.注册驱动
            Class.forName(properties.getProperty("jdbc.driverClassName"));


            //3.获取连接
            for(int i=0;i<Integer.valueOf(properties.getProperty("jdbc.init"));i++){

                //获取连接
                Connection conn = DriverManager.getConnection(properties.getProperty("jdbc.url"),
                        properties.getProperty("jdbc.username"), properties.getProperty("jdbc.password"));

                //把连接放入集合
                conns.add(conn);

            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("创建数据库连接池失败!");
        }


    }


    /**
     * 获取链接
     * @return
     * @throws SQLException
     */
    @Override
    public Connection getConnection() throws SQLException {

        //1.获取被增强对象 真正的连接
        Connection connection = conns.removeFirst();

        //2.包装设计模式(装饰)
        return new MyConnection(connection);
    }


    //1.编写一个类,实现Connection接口  考虑的数据库太多了
    //2.继承ConnectionImpl,重写close方法
    //3.装饰设计模式(包装设计模式)
    // 3.1 编写一个类,实现与被增强对象相同的接口
    // 3.2 定义一个变量,记住被增强对象
    // 3.3 定义一个构造方法接收被增强对象
    // 3.4 覆盖想覆盖的方法
    // 3.5 对于不想覆盖的方法直接调用被增强对象的方法来实现
    // 动态代理

    //1.编写一个类,实现与被增强对象相同的接口
    class MyConnection implements Connection{

        //2.定义一个变量,记住被增强对象
        private Connection conn;

        //3.定义一个构造方法接收被增强对象
        public MyConnection(Connection conn){
            this.conn=conn;
        }

        //4.覆盖想覆盖的方法
        @Override
        public void close() throws SQLException {
             //还连接
            conns.add(conn);
        }

        //5.对于不想覆盖的方法直接调用被增强对象的方法来实现
//不想覆盖的方法此次省略。。。 
使用第三方数据库连接池

在这里插入图片描述
在这里插入图片描述

public class TestDataSource {

    public static void main(String[] args) throws Exception {

        //1.创建连接池
        ComboPooledDataSource dataSource=new ComboPooledDataSource();

        //2.通过set方法设置相关连接信息
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        dataSource.setMinPoolSize(5);
        dataSource.setMaxPoolSize(9);;


        //3.获取连接
        Connection connection = dataSource.getConnection();

        System.out.println(connection);

    }

}
druid

在这里插入图片描述

public class TestDataSource {

    public static void main(String[] args) throws Exception {

        //1.创建连接池
        DruidDataSource dataSource=new DruidDataSource();


        //2.通过set方法设置相关连接信息
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/jdbc");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setMinIdle(5);
        dataSource.setMaxActive(9);


        //3.获取连接
        Connection connection = dataSource.getConnection();

        System.out.println(connection);

    }

}
  • 22
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值