池(Pool)技术在一定程度上可以明显优化服务器应用程序的性能,提高程序执行效率和降低系统资源开销。这里所说的池是一种广义上的池,比如数据库连接池、线程池、内存池、对象池等。其中,对象池可以看成保存对象的容器,在进程初始化时创建一定数量的对象。需要时直接从池中取出一个空闲对象,用完后并不直接释放掉对象,而是再放到对象池中以方便下一次对象请求可以直接复用。其他几种池的设计思想也是如此,池技术的优势是,可以消除对象创建所带来的延迟,从而提高系统的性能。
要了解Java连接池我们先要了解数据库连接池(connection pool)的原理,Java连接池正是数据库连接池在Java上的应用。——我们知道,对于共享资源,有一个很著名的设计模式:资源池(Resource Pool)。
该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。
所以数据库连接池 并不是数据库里面的 概念,而是一种设计模式
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;这项技术能明显提高对数据库操作的性能。简单理解DataSource是一个管理数据库连接Connection对象的容器。可以这么看DataSource类似List
连接池只是存放数据库连接对象的一个缓冲池,需要数据连接的时候从缓冲池中取就行了
数据源 是一种数据库对编程提供的一个接口(javax.sql.DataSouce接口),每个数据源对应一个数据库。
数据源是指 数据的来源的概括,包含了数据库位置 和 数据库类型等信息,实际上是一种数据连接的抽象。 也可以说,你要得到的信息存放的地方的概括(包括 存放信息的数据库类型、数据库的地址等等信息的概括)。
使用数据库连接池的优点:
1、资源重用 2、更快的系统响应速度 3、新的资源分配手段 4、统一的连接管理,避免数据库连接的泄漏JDBC的数据库连接池使用javax.sql.DataSouce接口,任何想要使用JDBC数据源方法的第三方组件都需要实现该接口。
典型的两种开源数据源
1、DBCP的实现数据源为BasicDataSouce,可以使用BasicDataSourceFactory的createDataSource(Properties properties)方法来创建数据源。使用properties配置文件。
2、C3P0的实现数据源为ComboPooledDataSource。c3p0数据源是使用c3p0-config.xml配置文件的,不要修改它的默认名字。否则加载不了。
备注:Spring推荐使用DBCP数据源、Hibernate推荐使用C3P0数据源。Tomcat默认使用的是DBCP数据库连接池. DBCP稳定性更强,C3P0数据源并发性高的时候更有优势。基于Java代码方式
//初始化对象 ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost/test"); dataSource.setUser("root"); dataSource.setPassword("admin"); dataSource.setInitialPoolSize(5); ...设置参数基于配置文件方式
c3p0-config.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <named-config name="c3p0"> <!-- 指定连接数据源的基本属性 --> <property name="user">root</property> <property name="password">admin</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property> <!-- 若数据库中连接数不足时, 一次向数据库服务器申请多少个连接 --> <property name="acquireIncrement">5</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>初始化数据源如下:
// 使用new ComboPooledDataSource(String // configName)初始化获得数据源对象,configName为c3p0-config配置文件的named-config标签的name属性值 ComboPooledDataSource dataSource = new ComboPooledDataSource("c3p0"); Connection connection = dataSource.getConnection(); 备注:数据源只需要初始化一次就行了,所以应该将其初始化放入static代码块中备注:
数据库连接池获得的Connection对象的close()方法并不是真正的关闭资源,而是把数据库连接资源归还给数据库连接池。因为通过数据源获得的连接对象其实是一个代理对象并不是真正的Connection对象。
在代码中使用DriverManager获得数据库连接的方式中,客户程序得到的连接对象是物理连接,调用连接对象的close()方法将关闭连接,而采用连接池技术,客户程序得到的连接对象是连接池中物理连接的一个句柄,调用连接对象的close()方法,物理连接并没有关闭,数据源的实现只是删除了客户程序中的连接对象和池中的连接对象之间的联系.
参考1 参考2 参考3