转自http://www.cnblogs.com/xing901022/p/4571855.html https://blog.csdn.net/lgm277531070/article/details/6711177
数据库连接池这个概念应该都不陌生,在Java中连接池也就是数据库的连接池,它是一种采用连接复用的思想避免多次连接造成资源的浪费机制。
最常见的连接池就是DBCP和C30P了,在tomcat中默认使用的DBCP的连接池,在Hibernate中则默认使用的是C3P0。他们的区别对于使用者来说最明显的就是,默认情况下DBCP不提供空闲连接的释放,需要手动开启。
下面介绍下Tomcat中数据连接池的配置及使用。
本篇依赖一个概念——JNDI,可以参考前面的博客:JNDI资源详解。
对于JNDI,可以简单理解成Tomcat中的资源池,通过一些特有的名字与特定的资源相对应,类似一个map,可以简单的通过名字获取到该资源。
那么本篇中JNDI数据源就是通过配置一个数据源的资源,在应用中通过该名称获取到数据库连接,进行操作。这样就省去了每次连接数据库的步骤。
连接池的概念,应该都不陌生了。部分内容可以参考:几个主流的连接池
这里简单说明下,如果单独在应用使用连接池,可能只是在应用运行时创建连接池。而tomcat配置数据源可以在tomcat容器启动时就初始化连接池,停止tomcat时才释放资源,其部署的应用可以根据JNDI的声明,在应用中共享使用该资源。
因此一个是应用中的连接池(即一个应用中不同的业务使用该连接池,比如注册新用户与购买商品),一个可以扩大到多应用的连接池,具体使用的还要看业务需求。
另外,tomcat中默认使用的DBCP连接池,其jar包位于CATALINA_HOME/lib下,tomcat-dbcp.jar。
需要注意的是,默认情况下dbcp不会去释放空闲的连接。比如,我们在编码时,拿到一个连接执行业务操作,但是没有进行释放。此时,DBCP连接池不会放回到空闲队列中。如果再有新的连接,会分配其他的连接。当连接数目过大时,就会造成连接的阻塞。
可以通过配置某些属性来自动回收连接,首先设置removeAbandoned="true"开启回收,然后设置removeAbandonedTimeout="300"设置连接的时间,超过该时间就会自动收回。
具体内容可以参考:DBCP文档
按照下面几个步骤:
1 放置mysql驱动:可以到这里下载
2 创建数据库插入数据
3 配置JNDI资源(context.xml以及web.xml)
4 创建JSP验证结果
1 放置驱动
在tomcat根目录下的Lib中放置mysql驱动。
2 创建数据库表并添加数据
可以参考下面的SQL脚本:
/*
SQLyog v4.05
Host - 4.1.11-nt : Database - test
*********************************************************************
Server version : 4.1.11-nt
*/
create database if not exists `test`;
USE `test`;
/*Table structure for table `test`.`stu` */
drop table if exists `test`.`stu`;
CREATE TABLE `stu` (
`id` int(11) NOT NULL default '0',
`name` char(1) default NULL,
`age` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*Data for the table `test`.`stu` */
insert into `test`.`stu` values (0,'x',26),(1,'z',27),(2,'w',25);
3 配置JNDI资源
首先在context.xml中添加
其中username为你的用户名,password是密码。
maxActive指定最大的连接数,maxIdle指定最大的空闲连接数(即没有连接时,保存多少连接),maxWait指定最大的等待连接数。
然后在web.xml中配置指定的资源名称(不是必须的)
DB Connection
jdbc/TestDB
javax.sql.DataSource
Container
4 创建JSP页面,输出信息
按照下面的代码创建,并释放连接:
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="javax.naming.*,java.sql.*,javax.sql.*"
pageEncoding="UTF-8"%>
Insert title here
Results
<%
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource)envContext.lookup("jdbc/TestDB");
Connection conn = ds.getConnection();
String sql = "select * from stu";
PreparedStatement st = conn.prepareStatement(sql);
ResultSet rs = st.executeQuery();
while(rs.next()){
out.println("name:"+rs.getString(2)+" age:"+rs.getInt(3)+"
");
}
if(rs!=null){
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
%>
最后的执行结果:
其他的配置如Oracle和PostgreSQL仅仅是需要的数据库驱动和创建的JNDI名称不同:
例如,在oracle中,context.xml中配置如下:
在PostgreSQL中配置如下:
tomcat配置jndi有全局配置和局部配置。大致的有以下三种配置方式:
第一种:全局配置。
1)在tomcat的conf文件夹下的context.xml配置文件中加入:
2)在项目的web.xml中加入资源引用:
JNDI DataSource
jndi/mybatis
javax.sql.DataSource
Container
其中res-ref-name值要和context.xml的name值一致。
3)jndi测试方法:
public void testJNDI() throws NamingException, SQLException{
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup("java:comp/env/jndi/mybatis");
Connection conn = ds.getConnection();
System.out.println(conn.isClosed());
}
4)在jsp中调用加载jndi方式,不可以直接用main方法测试,必须通过启动容器从jsp中调用:
TestPageAccessURL test = new TestPageAccessURL();
test.testJNDI();
第二种:局部配置(不推荐)。
1)在tomcat的server.xml的
其他配置同第一种方式。
第三种:局部配置。
1)在项目的META-INFO下面新建context.xml。加入:
其他配置同第一种方式。
总结:如果要配置局部的话,推荐使用第三种方式,这样不依赖tomcat了。但是还是推荐使用第一种方式好,虽然依赖tomat,但是是全局的,而且可以配置多个。对于以后切换使用方便。在项目的web.xml中添加的资源引用可有可无。
【1】几种主流的连接池:http://developer.51cto.com/art/201006/207768.htm
【2】DBCP官方文档:http://commons.apache.org/proper/commons-dbcp/configuration.html
【3】Tomcat JNDI Database:http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html