数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。因此提出了一种概念--数据库连接池。
数据库连接池的基本原理是在内部对象池中,维护一定数量的数据库连接,并对外暴露数据库连接获取和返回方法。当程序中需要建立数据库连接时,只需从内存中获取一个数据库连接来用,而不是新建一个数据库连接,在使用完毕后,只需放回内存既可。对于连接的建立和断开都由连接池自己管理。
下面通过tomcat连接池的配置具体了解一下连接池的应用。
步骤1:打开tomcat管理界面,登陆,配置,生成配置内容,然后再走步骤2。(试验了两种从管理界面配置的方法都没成功,暂时无果,所以就直接走步骤2吧)
步骤2:直接在apache-tomcat-7.0.69\conf下找到context.xml文件,配置成如下形式:
<?xml version='1.0' encoding='utf-8'?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Resource name="jdbc/mydrp"
auth="Container"
type="javax.sql.DataSource"
username="root"
password="123"
maxIdle="30"
maxWait="10000"
maxActive="100"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/drp" />
</Context>
具体参数说明:
①name:即JNDI NAME,是指注册到JDNI输上的名称。
②username:访问数据库的用户名称。
③password:访问数据库的用户密码。
④maxIdle:最大空闲连接数,表示没有数据库连接时,连接池也必须保持最大空闲连接数,设置为0没有限制。
⑤maxWait:建立连接等待时间,单位:毫秒,设置我-1无限制。
⑥maxActive:最大活跃连接数,指同时可以有多少个连接,设置0为无限制。
⑦driverClassName:连接数据库的驱动名称。
⑧url:连接数据库的URL。
配置好之后,就形成了DBCP Pool,那么所有用该tomcat的项目都可以使用该连接池了。现在context.xml是属于tomcat服务器的,如果只想让唯一一个项目使用,则将context.xml剪切到下图目录下:
注意:DBCP连接池装载时使用的是Common类加载器,该装载器中没有我们所需要的jdbc的驱动,我们项目中倒是有jdbc的驱动,但是那是属于Web项目的,根据双亲委派机制,在Common加载器加载时无法获取Web项目中的类,所以必须把相关的驱动复制到Common类加载器的类存放的文件夹中。因为我用的是MyEclipse自带的tomcat,所以具体的路径如下:
完事之后,需要重新启动tomcat,测试页面JSP代码如下:
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@ page import="javax.naming.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="java.sql.*"%>
<%
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
//new DBCP....
Context ctx = new InitialContext();
//通过JNDI查找DataSource
DataSource ds = (DataSource) ctx
.lookup("java:comp/env/jdbc/mydrp");
conn = ds.getConnection();
pstmt = conn.prepareStatement("select * from t_user");
rs = pstmt.executeQuery();
while (rs.next()) {
out.println(rs.getString("user_id") + ", "
+ rs.getString("user_name"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
if (conn != null) {
//将Connection放到连接池中
conn.close();
}
}
%>
效果如下:
补充:数据库连接池一般都会在使用过连接之后,再将connection放回到连接池中。如果不放回的话,就代表该连接一直在使用,那么连接池的可连接数就少一个,一旦超过maxActive设置的值,就会报错。