首先弄明白这项技术为什么而出现:
你建了一个装修公司,每次接到活都要自己去找人,辛辛苦苦找到20个人,雇主说只要15个人就能干,你找了别人也不能失信啊,只能20个人干15个人的活,就造成了浪费,完活后,又得挨个叫出去say bye,刚赶走,又来活了,你两眼一黑,我去哪找啊,走着走着到了一个劳动市场,一个头和你打招呼,要人吗,我手里有一帮人,你要多少就给多少,用完了再换回来,你一听这不就把问题都解决了吗,不用自己去找人,赶人,还不用自己管理这些人,还想要多少就有多少,后悔怎么早没发现啊。数据库连接池的出现也是如此,连接的建立销毁管理太浪费了,能重复利用还不用自己管理那不是爽歪歪。
它又是怎么实现的:
在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
所以数据库连接池能干什么:
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接会报错来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
这里面有几个池参数需要明白:
初始化连接数量 initialSize:初始化时候数据库连接数量
最大连接数 maxActive :达到最大连接数,不再创建,加入等待队列
最大空闲连接数 maxIdle:最大空闲数据库连接数量,大于这个就要销毁了
最小空闲链接数 minIdle:最小空闲数据库连接数量,到达这个数字就要新建连接了
增量:一次创建的最小单位
最大等待时间时间 :到达设置时间就抛异常
Java中开源的数据库连接池有很多,常用的就两种:DBCP和C3P0
DBCP也是被慢慢抛弃,重点学习一下这两种。
万物皆对象,想在java中使用连接池也得依靠对象,所以java中的连接池都必须实现DateSource接口。
另外连接池也是依靠JDBC四大连接参数来创建连接对象,但是DBCP和C3P0底层实现不太一样。
还有一点是使用连接池提供的对象使用close()方法不是关闭连接,而是把连接归还到连接池中。
DBCP
DBCP的实现依赖于两个jar包
下载地址为http://commons.apache.org/
首先来看一下例子,DBCP池类是BasicDataSource这个DateSource的实现类
import java.sql.Connection; import java.sql.SQLException; import org.apache.commons.dbcp2.BasicDataSource; public class MyConnection { public void getCon() throws SQLException{ BasicDataSource bs=new BasicDataSource(); bs.setDriverClassName("com.mysql.jdbc.Driver"); bs.setUrl("jdbc:mysql://localhost:3306/zoo"); bs.setUsername("root"); bs.setPassword("123456"); //设置初始化连接数 bs.setInitialSize(10); //设置最小空闲连接 bs.setMinIdle(3); //设置最大空闲时间 bs.setMaxWaitMillis(1000); Connection con=bs.getConnection(); con.close(); } }
还是使用JDBC四大连接参数,因为DBCP使用的是装饰者模式,底层还是使用Connection对象的方法,只不过把close()方法给增强了,变成了归还给连接池。
C3P0
C3P0是现在主要的数据库连接池使用,使用jar包
这里面因为使用的是mysql,所以第二个就不需要使用,下载地址是
https://sourceforge.net/projects/c3p0/files/latest/download?source=files
C3P0的池类是 ComboPooledDataSource
import java.beans.PropertyVetoException; import java.sql.Connection; import java.sql.SQLException; import com.mchange.v2.c3p0.ComboPooledDataSource; public class Cp30Demo { public void fun() throws PropertyVetoException, SQLException { ComboPooledDataSource bs = new ComboPooledDataSource(); bs.setDriverClass("com.mysql.jdbc.Driver"); bs.setJdbcUrl("jdbc:mysql://localhost:3306/zoo"); bs.setUser("root"); bs.setPassword("123456"); Connection con = bs.getConnection(); con.close(); } }
C3P0也可以使用配置文件,不过有两个要求:
1.文件名称必须叫做 c3p0-config.xml
2.文件路径必须在src下
<?xml version="1.0" encoding="UTF-8"?> <cp30-config> <default-config> <property name="jdbcUrl">jdbc:mysql://localhost:3306/zoo</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">123456</property> </default-config> </cp30-config>
这样在创建线程池时就可以
/** * @author WangXinwei *创建线程时对象时,自动加载配置文件 */ public void fun1() throws SQLException{ ComboPooledDataSource bs = new ComboPooledDataSource(); Connection con = bs.getConnection(); con.close(); }
C3P0底层是使用动态代理来实现的,以后再了解这个。
Tomcat配置线程池
1.配置JNDI资源
JNDI是java命名和目录接口。JNDI的作用是:在服务器上配置资源,然后通过统一的方式来获取配置的资源。
我们需要配置的是线程池,这样项目中就可以统一获取连接池对象
第一种:全局配置
1)在tomcat的conf文件夹下的context.xml配置文件中加入:
<Resource name="mysqlDataSource" type="com.mchange.v2.c3p0.ComboPooledDataSource" factory="org.apache.naming.factory.BeanFactory" user="root" password="123456" driverClass="com.mysql.jdbc.Driver" jdbcUrl="jdbc:mysql://localhost:3306/zoo" />
2)在项目的web.xml中加入资源引用:
<resource-ref> <description>JNDI DataSource</description> <res-ref-name>sqlconn</res-ref-name> <res-ref-type>javax.sql.DataSource</res-ref-type> <res-auth>Container</res-auth> </resource-ref>
第二种:局部配置(不推荐)。
1)在tomcat的server.xml的<host>标签内,添加:
<Context path="" docBase=""> <Resource name="mysqlDataSource" type="com.mchange.v2.c3p0.ComboPooledDataSource" factory="org.apache.naming.factory.BeanFactory" user="root" password="123456" driverClass="com.mysql.jdbc.Driver" jdbcUrl="jdbc:mysql://localhost:3306/zoo" /> </Context>
其他配置同第一种方式。
第三种:局部配置。
1)在项目的META-INFO下面新建context.xml。加入:
<?xml version="1.0" encoding="UTF-8"?> <Context> <Resource name="mysqlDataSource" type="com.mchange.v2.c3p0.ComboPooledDataSource" factory="org.apache.naming.factory.BeanFactory" user="root" password="123456" driverClass="com.mysql.jdbc.Driver" jdbcUrl="jdbc:mysql://localhost:3306/zoo" /> </Context>
其他配置同第一种方式。
还可以在 D:apache-tomcat-7.0.82confCatalinalocalhost下创建与项目名相同的xml
<?xml version="1.0" encoding="UTF-8"?> <Context> <Resource name="mysqlDataSource" type="com.mchange.v2.c3p0.ComboPooledDataSource" factory="org.apache.naming.factory.BeanFactory" user="root" password="123456" driverClass="com.mysql.jdbc.Driver" jdbcUrl="jdbc:mysql://localhost:3306/zoo" /> </Context>
总结:如果要配置局部的话,推荐使用第三种方式,这样不依赖tomcat了。但是还是推荐使用第一种方式好,虽然依赖tomat,但是是全局的,而且可以配置
多个。对于以后切换使用方便。
在项目的web.xml中添加的资源引用可有可无。
2.获取资源
Context cxt = new InitialContext(); //得到路口 Context initcxt=(Context) cxt.lookup("java:comp/env"); //二次获取 DataSource source= (DataSource) initcxt.lookup("jdbc/dataSource"); Connection conn=source.getConnection(); System.out.println("这是"+conn+"111"); conn.close();