数据库连接池
一、直接获取数据库链接的缺点
用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。
二、使用数据库连接池优化程序性能
数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
如下图所示:
三、开源数据库连接池
通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。
也有一些开源组织提供的数据源:
- DBCP连接池
- C3P0连接池
3.1 DBCP连接池
使用DBCP连接池,需要导入两个jar包
- commons-dbcp-1.2.2.jar :连接池的实现
- Commons-pool.jar:连接池实现的依赖库
3.2 在应用程序中加入DBCP连接池(两种方式:BasicDataSource、BasicDataSourceFactory)
BasicDataSource方式(硬编码):BasicDataSource对象设置各种数据
-
导入相关jar包
commons-dbcp-1.2.2.jar、commons-pool.jar
-
硬编码获取connection连接
public static DataSource getDataSource(){
BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("com.mysql.jdbc.Driver");
bds.setUrl("jdbc:mysql://localhost:3306/student");
bds.setUsername("root");
bds.setPassword("123456");
bds.setInitialSize(20);
bds.setMaxActive(10);
?
return bds;
}
?
public static void main(String[] args) throws Exception{
System.out.println(getDataSource().getConnection());
}
BasicDataSourceFactory方式: 配置方式(.properties文件)
-
导入相关jar包
commons-dbcp-1.2.2.jar、commons-pool.jar
-
在类目录下加入dbcp的配置文件:dbcpconfig.properties(此处遇到一个错误将在文后写)
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student
username=root
password=123456
?
#<!-- 初始化连接 -->
initialSize=10
?
#最大连接数量
maxActive=50
?
#<!-- 最大空闲连接 -->
maxIdle=20
?
#<!-- 最小空闲连接 -->
minIdle=5
?
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
-
通过读取配置文件获取connection连接
public static DataSource getDataSourceByProfile() throws Exception{
?
DataSource dbcp = null;
Properties properties = new Properties();
//读取配置文件转化为输入流的形式
InputStream inputStream = DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
?
//加载配置文件的输入流
properties.load(inputStream);
?
//获取数据库连接
dbcp = BasicDataSourceFactory.createDataSource(properties);
?
return dbcp;
?
}
3.3 c3p0连接池
c3p0与dbcp区别
- dbcp没有自动回收空闲连接的功能
- c3p0有自动回收空闲连接功能
3.4 在应用程序中加入c3p0连接池(两种方式:硬编码和配置文件)
硬编码方式
-
导入相关jar包
c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar,如果操作的是mysql数据库需另加入mysql-connector-java-5.1.49-bin.jar
-
应用程序获取数据库连接
public static DataSource getDataSourceByC3P0() throws Exception{
ComboPooledDataSource c3p0 = new ComboPooledDataSource();
c3p0.setDriverClass("com.mysql.jdbc.Driver");
c3p0.setJdbcUrl("jdbc:mysql://localhost:3306/student");
c3p0.setUser("root");
c3p0.setPassword("123456");
c3p0.setInitialPoolSize(5);
c3p0.setMaxPoolSize(15);
?
return c3p0;
}
?
public static void main(String[] args) throws Exception{
System.out.println(getDataSourceByC3P0().getConnection());
}
配置文件方式
-
导入相关jar包
c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar,如果操作的是mysql数据库需另加入mysql-connector-java-5.1.49-bin.jar
-
编写配置文件c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<!-- 如果要研究某个xml中可以设置哪些属性。找相关类的 属性 或者setXxx()-->
<property name="user">root</property>
<property name="password">123456</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/student</property>
<property name="checkoutTimeout">30000</property>
</default-config>
?
?
<named-config name="admin">
<property name="user">root</property>
<property name="password">123456</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/student</property>
<property name="checkoutTimeout">20000</property>
?
</named-config>
?
</c3p0-config>
-
程序中获取数据库连接
public static DataSource getDataSourceByC3P0XML(){
?
ComboPooledDataSource c3p0 = new ComboPooledDataSource("admin");
?
return c3p0;
}
?
public static void main(String[] args) throws Exception{
System.out.println(getDataSourceByC3P0XML().getConnection());
}
}
四、配置Tomcat数据源
4.1 JNDI技术简介
JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于javax.naming包, 这套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需 通过名称检索即可。其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。
我们可以通过配置context.xml和web.xml文件实现JNDI获取Tomcat数据库连接池
context.xml
?
<Context>
?
<Resource name = "student" auth = "Container" type = "javax.sql.DataSource" maxActive = "400"
maxIdle = "20" maxWait = "5000" username = "root" password="123456" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/student">
?
</Resource>
?
</Context>
web.xml
?
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
?
?
<resource-ref>
<res-ref-name>student</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
?
</web-app>
服务器创建好数据源之后,我们的应用程序又该怎么样得到这个数据源呢,Tomcat服务器创建好数据源之后是以JNDI的形式绑定到一个JNDI容器中的,我们可以把JNDI想象成一个大大的容器,我们可以往这个容器中存放一些对象,一些资源,JNDI容器中存放的对象和资源都会有一个独一无二的名称,应用程序想从JNDI容器中获取资源时,只需要告诉JNDI容器要获取的资源的名称,JNDI根据名称去找到对应的资源后返回给应用程序。
java程序如何获取数据库连接
try {
Class.forName("com.mysql.jdbc.Driver") ;
Context cxt = new InitialContext();
DataSource ds = (DataSource)cxt.lookup("java:comp/env/student");
connection = ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
}
学习过程中遇到的错误
无论使用哪一种数据库连接池时,都可能会遇到访问配置文件的情况
在使用配置文件获取DBCP和C3P0的数据库连接时出现以下错误:
可我明明配置了c3p0-config.xml 配置文件 ,却并未加载,发现是文件位置问题,将c3p0-config.xml移至resources目录下解决。