数据库连接池是什么?

数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。

在对数据库进行操作之前都要先获取数据库连接,然后才能向后进行操作,增删改查,获取结果集,浪费时间的地方就是在获取数据库连接上,以往每次操作的时候,先获取连接,操作完之后关掉连接,这么一次一次,时间都浪费在获取连接上了,我们需要的就是一个数据库连接池,先创建好一定数量的连接放在池子里,当我们要用的时候,去池子中去找可用的连接,当用完之后,再把连接放回池子中,这样我们用的连接都是池子负责管理的,每次用完之后只要放回去,这样相比于之前的获取到连接,用完关闭速度很快,只是把连接拿来不用每次都创建,关闭,可以省很多的时间。

postgresql 连接池 多slave java 连接池连接数据库_System

使用c3p0可以很轻松地构建数据库连接池,是一个开源的项目,https://sourceforge.net/projects/c3p0/files/?source=navbar下载网址,一个压缩包中包含jar包和例子,说明

postgresql 连接池 多slave java 连接池连接数据库_Source_02

需要的jar包,导入我们的项目中就能使用了

使用单例模式(饿汉式)构建数据库连接池,

private static ComboPooledDataSource dataSource;
    private static ConnectionManager connectionManager = new ConnectionManager();
    private ConnectionManager(){
        try {
            //ComboPooledDataSource cpds = new ComboPooledDataSource();
            // cpds.setDriverClass(“org.postgresql.Driver”);
            // 加载jdbc驱动程序cpds.setJdbcUrl(“jdbc:postgresql:localhost / testdb”);
            // cpds.setUser( “swaldman”);
            // cpds.setPassword( “测试密码”);
            // 下面的设置是可选的 -  c3p0可以使用默认值
            // cpds.setMinPoolSize(5);
            // cpds.setAcquireIncrement(5);
            // cpds.setMaxPoolSize(20); // DataSource cpds现在是一个完全配置和可用的汇集数据源...
            dataSource = new ComboPooledDataSource();
            dataSource.setUser("root");
            dataSource.setPassword("root");
            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/mail");
            dataSource.setDriverClass("com.mysql.jdbc.Driver");
            dataSource.setInitialPoolSize(5); //初始化连接数
            dataSource.setMinPoolSize(1);//最小连接数
            dataSource.setMaxPoolSize(20);//最大连接数
            dataSource.setMaxStatements(50);//最长等待时间
            dataSource.setMaxIdleTime(60);//最大空闲时间,单位毫秒
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
    }

    public static ConnectionManager getInstance(){
        return connectionManager;
    }
    public synchronized Connection getConnection() {
        Connection conn = null;
        try {
             conn=dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }


在下载的说明文档中也介绍了使用方法

postgresql 连接池 多slave java 连接池连接数据库_Source_03

在main方法中测试,输出两种方法所用的时间

public static void main(String[] args) throws SQLException {
        for(int i=0;i<50;i++) {
            long begin = System.currentTimeMillis();
            Connection conn = ConnectionManager.getInstance().getConnection();
            PreparedStatement ps = conn.prepareStatement("SELECT * FROM USER WHERE id=2");
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {

            }
            conn.close();
            ps.close();
            rs.close();
            long end = System.currentTimeMillis();
            System.out.print(end-begin+"  ");
        }
        System.out.println("-------------");
        for(int i=0;i<50;i++) {
            long begin = System.currentTimeMillis();
            Connection conn=null;
            try {
                Class.forName("com.mysql.jdbc.Driver");
                String url = "jdbc:mysql://localhost:3306/mail";
                String username = "root";
                String password = "root";
                conn = DriverManager.getConnection(url, username, password);
                PreparedStatement ps = conn.prepareStatement("SELECT * FROM USER WHERE id=2");
                ResultSet rs = ps.executeQuery();
                while (rs.next()) {

                }
                conn.close();
                ps.close();
                rs.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            long end = System.currentTimeMillis();
            System.out.print(end - begin+" ");
        }
    }


输出:

postgresql 连接池 多slave java 连接池连接数据库_Source_04

利用数据库连接池第一次使用耗时时间长,以后平均用时均为1ms,不使用连接池的代码平均都在15ms左右