JDBC--数据库连接池
1、在使用开发基于数据库的web程序时,传统的模式是现在主程序中简历数据库连接,当进行完sql操作之后断开数据库连接。这种模式存在一些问题:
--普通的JDBC数据库连接使用DRiverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证用户名和密码。需要数据库连接的时候,就向数据库要求一个,执行完之后再断开连接。这样的方式会消耗大量的资源和时间。数据库的连接资源并没有得到很好的重复利用。当同时在线用户数量很大时,频繁地连接数据库将占用很多系统资源,容易造成崩溃;
--对于每一次数据库连接,使用完后都需要断开。否则,若程序出现异常而未正常结束,将导致数据库系统中的内存泄露,最终将导致重启数据库。
--这种开发不能控制被创建的连接对象数,系统资源会被毫无顾忌地分配出去,如果连接过多,也可能导致内存泄露,服务器崩溃。
2、为了解决上述的数据库连接问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库建立一个"缓冲池",预先在缓冲池中放入一定数量的连接,当需要简历数据库连接时,只需从缓冲池中取出一个,使用完毕之后再返回去。
3、数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
4、数据库连接池的优点:
--1)资源重用;
--2)更快的系统反应速度;
--3)新的资源分配手段;
--4)统一的连接管理,避免数据库连接泄露。
5、在JDBC中,数据库连接池使用javax.sql.DataSource来表示,DataSource是一个接口,该接口通常由服务器提供实现,也有一些开源组织提供实现(如DBCP数据连接池、C3P0数据库连接池);DataSource通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把DataSource称为连接池。
6、DBCP数据连接池的使用:
--涉及到的包:1)commons-dbcp-1.4.jar;2)commons-pool-1.5.5.jar;
--直接创建DBCP的DataSource数据源
public void testDataSource() throws Exception{ //创建DBCP数据源实例 BasicDataSource dataSource = new BasicDataSource(); //为数据源实例指定必需的属性 dataSource.setUsername("scott"); dataSource.setPassword("orcl"); dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:orcl"); dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver"); //设置数据源的其他属性 //1、指定数据库连接池中初始化连接数的个数 dataSource.setInitialSize(10); //2、指定最大连接数:同一时刻可以同时向数据库申请的连接数 dataSource.setMaxActive(50); //3、指定最小连接数:在数据库连接池中保存的最少空闲连接的数量 dataSource.setMinIdle(5); //4、等待数据库连接池分配连接的最长时间(单位:ms),若超出该时间,会抛出异常 dataSource.setMaxWait(5000); //从DataSource数据源中获取连接 Connection conn = dataSource.getConnection(); System.out.println(conn); }
--通过DataSourceFactory类来创建DataSource数据源:
public void testDataSourceFactory() throws Exception{ //首先将DataSource数据源的属性信息放在配置文件中,其中配置文件的键值对必须是DataSource中的属性 Properties properties = new Properties(); InputStream inStream = new FileInputStream("dbcp.properties"); //加载dbcp的属性文件 properties.load(inStream); //通过DataSourceFactory来创建DataSource数据源 DataSource dataSource = BasicDataSourceFactory.createDataSource(properties); BasicDataSource basicDataSource = (BasicDataSource)dataSource; System.out.println(basicDataSource.getMaxWait()); }
#配置信息
username=scott password=orcl1 url=jdbc:oracle:thin:@localhost:1521:orcl driverClassName=oracle.jdbc.driver.OracleDriver initialSize=10 maxActive=50 minIdle=5 maxWait=5000
--上面两张方法中推荐使用第二种,因为通过第二种方法来创建数据源更具有灵活性,可以直接修改配置文件来设置数据源的相应属性;另外第二种方法创建数据源的方法是透明的,我们无需知道它是如何创建的。
7、C3P0数据库连接池的使用:
--涉及到的包:c3p0-0.9.1.2.jar
--代码实现一:
public void testC3p0() throws Exception { ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass( "oracle.jdbc.driver.OracleDriver" ); cpds.setJdbcUrl( "jdbc:oracle:thin:@localhost:1521:orcl" ); cpds.setUser("scott"); cpds.setPassword("orcl"); System.out.println(cpds.getConnection()); }
--代码实现二(通过配置文件实现):
public void testC3p0ConfigFile() throws SQLException{ DataSource dataSource = new ComboPooledDataSource("helloc3p0"); System.out.println(dataSource.getConnection()); ComboPooledDataSource cpds = (ComboPooledDataSource)dataSource; System.out.println(cpds.getAcquireIncrement()); }
--配置文件c3p0-config.xml:
<c3p0-config> <named-config name="helloc3p0"> <!-- 数据源的基本属性 --> <property name="user">scott</property> <property name="password">orcl</property> <property name="driverClass">oracle.jdbc.driver.OracleDriver</property> <property name="jdbcUrl">jdbc:oracle:thin:@localhost:1521:orcl</property> <!-- 若数据库中连接数不足时,一次性向数据库服务器申请指定数量的连接 --> <property name="acquireIncrement">3</property> <!-- 初始化数据库连接池时连接的数量 --> <property name="initialPoolSize">5</property> <!-- 数据库连接池中的最小的数据库连接数 --> <property name="minPoolSize">5</property> <!-- 数据库连接池中的最大的数据库连接数 --> <property name="maxPoolSize">10</property> <!-- C3P0数据库连接池可以维护的最大Statement个数 --> <property name="maxStatements">20</property> <!-- 每个连接同时可以使用的Statement对象的个数 --> <property name="maxStatementsPerConnection">5</property> </named-config> </c3p0-config>