jdbc学习----5.数据库连接池

    技术2024-02-02  92

    数据库连接池

    问题引出

    在使用开发基于数据库的web程序时,传统的模式基本是按以下步骤: 在主程序(如servlet、beans)中建立数据库连接进行sql操作断开数据库连接 这种模式开发存在的问题: 数据库的连接资源并没有得到很好地重复利用,多人在线可能造成服务器的崩溃对于每一次数据库连接,使用完都得断开,如果程序异常未能关闭,也可能导致内存泄漏,最终导致重启数据库这种开发不能控制被创建的连接对象数,系统资源将毫无顾忌的分配出去,如果连接过多,也可能导致内存泄漏(对象不能被回收,一直占用系统资源),服务器崩溃

    数据库连接池技术

    为了解决传统开发中的数据库连接问题,可以采用数据库连接池技术数据库连接池的基本思想:就是为数据库连接诶建立一个缓冲池,预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需要从缓冲池中取出一个,使用完毕后再放回去数据库连接池负责分配、管理和释放数据库连接,他允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个数据库连接池在初始化时将创建一定数量的连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的,无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量,连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入等待队列中。

    多种开源的数据库连接池

    JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由服务器(Weblogic,WebSphere,Tomcat)提供实现,也有一些开源组织提供实现: DBCP是Apache提供的数据库连接池,Tomcat子代dbcp数据库连接池,速度相对c3p0较快,但是存在bugc3p0是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性一般Proxool是sourceforge下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一些BoneCP是一个开源组织提供的数据库连接池,速度快Druid是阿里提供的数据库连接池,集各家之优点于一身,后期都是使用这个****

    DataSource:数据源,包含连接池和连接池管理两部分,用来取代DriverManager获取连接,获取速度快,同时可以大幅度提供商数据库访问速度

    c3p0

    初体验:

    @Test public void test1() throws Exception { ComboPooledDataSource cpds = new ComboPooledDataSource(); //四大参数 cpds.setDriverClass("com.mysql.cj.jdbc.Driver"); cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true"); cpds.setUser("root"); cpds.setPassword("123456"); cpds.setInitialPoolSize(10);//初始数据库连接池中的连接数 Connection connection = cpds.getConnection(); System.out.println(connection); DataSources.destroy(cpds);//销毁c3po连接池,一般不用 connection.close(); cpds.close(); }

    使用配置文件:

    @Test public void test2() throws Exception{ ComboPooledDataSource cpds = new ComboPooledDataSource(); Connection connection = cpds.getConnection(); System.out.println(connection); connection.close(); cpds.close(); }

    配置文件示例:

    <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <!-- 这是默认配置信息 --> <default-config> <!-- 连接四大参数配置 --> <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useSSL=false&amp;serverTimezone=UTC&amp;allowPublicKeyRetrieval=true&amp;rewriteBatchedStatements=true</property> <property name="driverClass">com.mysql.cj.jdbc.Driver</property> <property name="user">root</property> <property name="password">123456</property> <!-- 池参数配置 --> <property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </default-config> <!-- 专门为oracle提供的配置信息 --> <named-config name="oracle-config"> <!-- 连接四大参数配置 --> <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useSSL=false&amp;serverTimezone=UTC&amp;allowPublicKeyRetrieval=true&amp;rewriteBatchedStatements=true</property> <property name="driverClass">com.mysql.cj.jdbc.Driver</property> <property name="user">root</property> <property name="password">123456</property> <!-- 池参数配置 --> <property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </named-config> </c3p0-config>

    dbcp2

    初体验:

    @Test public void test1() throws Exception{ //创建DBCP数据库连接池 BasicDataSource ds = new BasicDataSource(); //设置连接参数 ds.setUsername("root"); ds.setPassword("123456"); ds.setDriverClassName("com.mysql.cj.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true"); //设置其他属性等等 ds.setInitialSize(1); Connection connection = ds.getConnection(); System.out.println("连接:"+connection.getClass()); connection.close(); ds.close(); }

    使用配置文件:

    @Test public void test2() throws Exception{ Properties properties = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbconfig.properties"); properties.load(is); BasicDataSource ds = BasicDataSourceFactory.createDataSource(properties); Connection connection = ds.getConnection(); System.out.println(connection.getClass()); is.close(); connection.close(); ds.close(); }

    配置文件示例:

    driverClassName=com.mysql.cj.jdbc.Driver username=root password=123456 url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true

    Druid(德鲁伊)数据库连接池

    Druid可以说是目前最好的连接池了,也是我们最常用的. 配合配置文件使用:

    @Test public void test1() throws Exception { Properties properties = new Properties(); FileInputStream is = new FileInputStream(new File("src/main/resources/dbconfig.properties")); properties.load(is); DataSource dds = DruidDataSourceFactory.createDataSource(properties); Connection connection = dds.getConnection(); System.out.println(connection); connection.close(); }
    Processed: 0.014, SQL: 9