首页 > 数据库技术 > 详细

Java学习之数据库连接池

时间:2020-03-26 18:11:28      阅读:58      评论:0      收藏:0      [点我收藏+]

一、数据库连接池

出现缘由:数据库的连接对象创建工作,比较消耗性能。

工作原理:在内存中开辟一块空间(集合),并放置多个连接对象。需要连接的话,直接从内存空间中获取。不需要创建连接对象。使用完毕,归还连接对象。确保连接对象能循环利用。

二、自定义数据库连接池

通过数据库连接池工作原理,自定义数据库连接池需要以下几步:

①、内存中开辟空间

②、创建数据库连接对象,并放置到内存中

③、定义获取数据库连接对象的方法

④、定义释放(归还)数据库连接对象的方法

代码实现:

/**
* @Title: MyDataSource
* @Description: sun公司提供数据库连接池规范是以DataSource命名的
* @author: marw
* @date 2020/03/26 16:16:58
*/
public class MyDataSource implements DataSource {

    //①、开辟空间
    List<Connection> list=new ArrayList<Connection>();
    
    /**
     * ②、创建数据库连接对象,并放置到内存中
     */
    public MyDataSource() {
    for (int i = 0; i < 10; i++) {
        Connection connection = JDBCUtil.getConnection();
        list.add(connection);
    }
    }
    
    /**
     * ③、 sun公司 提供数据库连接池规范中包含了获取数据库连接对象的方法
     * 只需要重写此方法
     */
    @Override
    public Connection getConnection() throws SQLException {
    //内存扩容
    if (list.size() == 0) {
        for (int i = 0; i < 3; i++) {
        Connection connection = JDBCUtil.getConnection();
        list.add(connection);
        }
    }
    // 移除集合中第一个元素(数据库连接对象),并获取移除的元素
    return list.remove(0);
    }
    
    /**
     * ④、释放(归还)数据库连接对象
     */
    public void Liberate(Connection connection) {
    list.add(connection);
    }

... ...

}

使用自定义数据库连接池

public class TestPool {
    @Test
    public void testPool() {
    Connection connection=null;
    PreparedStatement ps =null;
    MyDataSource dataSource=null;
    try {
        MyDataSource dataSource=new MyDataSource();
        connection=dataSource.getConnection();
        
        String sql="insert into account values(?,?)";
        ps =connection.prepareStatement(sql);
        ps.setString(1, "qian");
        ps.setInt(2, 1000);
        ps.executeUpdate();
        
    } catch (SQLException e) {
        
        e.printStackTrace();
    }
    finally {
     dataSource.Liberate(connection);//释放连接对象 JDBCUtil.release(connection, ps); } } }

使用自定义数据库连接池,有以下几个问题

①、每次使用都需要自己创建新的连接池对象,那样的话每一次访问都会创建10连接池对象,这个需要使用单例解决

②、无法面向接口编程,Liberate方法,不想自定义方法可以重写Connection接口的close方法,让它实现归还连接对象。

 想要扩展Connection接口的close方法

  Ⅰ、直接修改方法

  Ⅱ、继承,必须知道Connection接口的实现类

  Ⅲ、装饰模式

使用装饰模式代码:

public class ConnectionWrap implements Connection {
    Connection connection=null;
    List<Connection> list=null;
    
    public ConnectionWrap(Connection connection,List<Connection> list) {
    super();
    this.connection=connection;
    this.list=list;
    }

    @Override
    public void close() throws SQLException {
    list.add(connection);
    }

    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {

    return connection.prepareStatement(sql);
    }

... ...

}

使用装饰模式对象

public class MyDataSource implements DataSource {

    //①、开辟空间
    List<Connection> list=new ArrayList<Connection>();
    
    /* 单例 start */
    private static MyDataSource dataSource=new MyDataSource();
    /**
     * ②、创建数据库连接对象,并放置到内存中
     */
    private MyDataSource() {
    for (int i = 0; i < 10; i++) {
        Connection connection = JDBCUtil.getConnection();
        list.add(connection);
    }
    }
    
    public static MyDataSource getInstance() {
    return dataSource;
    }
    /* 单例 end */
    
    /**
     * ③、 sun公司 提供数据库连接池规范中包含了获取数据库连接对象的方法
     * 只需要重写此方法
     */
    @Override
    public Connection getConnection() throws SQLException {
    //内存扩容
    if (list.size() == 0) {
        for (int i = 0; i < 3; i++) {
        Connection connection = JDBCUtil.getConnection();
        list.add(connection);
        }
    }
    // 移除集合中第一个元素(数据库连接对象),并获取移除的元素
    Connection conn=list.remove(0);
    
    // 装饰模式 返回Connection对象,进行装饰,使其对象的close方法,有归还功能
    Connection connection = new ConnectionWrap(conn, list);
    return connection;
    }
    
... ...

}

测试代码

public class TestPool {
    @Test
    public void testPool() {
    Connection connection=null;
    PreparedStatement ps =null;
    
    try {
        DataSource dataSource=MyDataSource.getInstance();
        connection=dataSource.getConnection();
        
        String sql="insert into account values(?,?)";
        ps =connection.prepareStatement(sql);
        ps.setString(1, "qian");
        ps.setInt(2, 1000);
        ps.executeUpdate();
        
    } catch (SQLException e) {
        
        e.printStackTrace();
    }
    finally {
        JDBCUtil.release(connection, ps);
    }
    }
}

三、开源连接池

 

Java学习之数据库连接池

原文:https://www.cnblogs.com/WarBlog/p/12575896.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!