一、应用程序直接获取数据库连接的缺点
用户每次请求服务器都需要向数据户获取连接,数据库创建连接通常需要消耗较大的资源。如果一个网站的访问量有上万次,无疑需要创建上万个数据库连接,极大地消耗数据库的资源,并且会加大服务器的负担,造成服务器内存溢出等问题。
二、使用数据路连接池的方式进行优化
数据库的连接池基本思想是为数据库建立一个“缓冲池”,预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完后再放回去。可以通过设定连接池最大连接数来防止与服务器无尽的连接,数据库连接池负责分配管理和释放数据库连接,允许应用程序重复使用现有的一个数据库连接,而不是新建立一个。
数据库连接池在初始化时创建一定数量的连接放到连接池中,这些连接的数量由最小连接数来指定,无论这些数据库是否被使用,连接池中都保证至少存在这么多数量的连接,连接池的最大连接数的设定限制了该连接池可拥有连接的最大数量,当应用程序持续向服务请求连接,并且超过连接池最大连接数时,超过这些请求当被加入到等待队列中。
数据库连接池最小连接数和最大连接数:
1、最小连接数是连接池一直保持的数据连接。如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费掉。
2、最大连接数是连接池能申请的最大连接数。如果数据连接请求超过此数,后面的数据连接请求将被加入到等待队列中,这会影响之后的数据库操作。
3、如果最小连接数与最大连接数相差太大,那么,最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
三、开源的数据库连接池
3.1 DBCP数据库连接池
DBCP 是apache软件基金组织下的开源数据库连接池,需要的两个jar包分别是
原生的写法如下:
BasicDataSource dataSource = null;
//1、创建数据源实例
dataSource = new BasicDataSource();
//2、为数据库实例自定必须的属性
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setUrl("jdbc:mysql:///test");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
//3、指定数据源的一些可选的属性
//1)指定数据库连接池中初始化连接数的个数
dataSource.setInitialSize(5);
// 2)指定最大的连接数:同一时刻可以向数据库申请的连接数
dataSource.setMaxActive(50);
//3)指定最小空闲连接数:在数据库连接池中保存的最少的连接的数量
dataSource.setMinIdle(5);
//等待数据库连接池分配连接的最长时间,单位为毫秒
dataSource.setMaxWait(6*1000);
System.out.println(dataSource.getConnection());
System.out.println(dataSource.getConnection().getClass());
在类路径下加入dpcp的配置文件进行“去耦”操作,配置文件内容如下:
#连接池设置
driver =com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://127.0.0.1:3306/test
user=root
password=123456
初始化链接
initialSize=10
最大连接数量
maxActive=50
最大空闲连接
maxIdle =20
最小空闲连接
minIdle=20
maxWait = 60000
------------------------------------------------
加载代码如下
Properties properties = new Properties();
InputStream inputStream = Main.class.getClassLoader().getResourceAsStream("jdbc.properties");
properties.load(inputStream);
DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
System.out.println(dataSource);
3.2 C3P0数据库连接池
需要的jar包
原生写法:
ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql:///peixun");
cpds.setUser("root");
cpds.setPassword("");
System.out.println(cpds.getConnection())
配置文件写法:
<c3p0-config>
<named-config name="helloc3p0">
<property name="user">root</property>
<property name="password"></property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///peixun</property>
<!--若数据库中连接数不足时,一次想数据库服务器申请多少连接-->
<property name="acquireIncrement">50</property>
<!--初始化数据库连接池时连接的数量-->
<property name="initialPoolSize">5</property>
<!--数据库连接池中的最小的数据库连接数-->
<property name="minPoolSize">50</property>
<!--数据库连接池中的最小的数据库连接数-->
<property name="maxPoolSize">1000</property>
<!--c3p0数据库连接池可以维护的Statement的个数-->
<property name="maxStatements">20</property>
<!--每个连接同时可以使用的Statement对象的个数-->
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
加载代码如下:
DataSource dataSource = new ComboPooledDataSource("helloc3p0");
System.out.println(dataSource.getConnection());
ComboPooledDataSource comboPooledDataSource =
(ComboPooledDataSource)dataSource;
System.out.println(comboPooledDataSource.getMaxStatements());