数据库连接是一种关键的有限的昂贵的资源 ,这在多用户网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标,数据库连接池正是针对这个问题提出的
数据库连接池负责分配 , 管理和释放数据库连接 , 它允许应用程序重复使用一个现有的数据库连接 , 而不是再重新建立一个 ; 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏 , 这样可以明显提高对数据库操作的性能
数据库连接池在初始化的时将创建一定数量的数据库连接放到连接池中 , 这些数据库连接的数量是又最小数据库连接数来设定的 , 无论这些数据库连接是否被使用 , 连接池都将一直保证至少拥有这么多的连接数 , 当应用程序向连接池请求的连接数超过最大连接数量时 , 这些请求将被加入到等待队列中 .
数据库连接池的最小连接数和最大连接数的设置要考虑到下列几个因素 :
1. 最小连接数是连接池一直保持的数据库连接 , 所以如果应用程序对数据库连接的使用量不大 , 将会有大量的数据库连接资源被浪费 .
2. 最大连接数是连接池申请的最大连接数 , 如果数据库连接请求超过次数 , 后面的数据库连接请求将被加入到等待对了中 , 这回影响之后的数据库操作
如果最小连接数与最大连接数相差太大 , 那么最先的连接请求将会获利 , 之后超过最小连接数量的连接请求等价于建立一个新的数据库连接 , 不过 , 这些小于最小连接数的数据库连接在使用完不会马上被释放 , 它将被放到连接池中等待重复使用或是空闲超时被释放 .
实例使用的 Tomcat 版本为 6.0
方法一: 在
Tomcat的conf/context.xml
中配置
在
Tomcat\apache-tomcat-6.0.33\conf
目录下的
context.xml
文件中配置
默认值如下:
<? xml version='1.0' encoding='utf-8' ?> < Context > < WatchedResource > WEB-INF/web.xml </ WatchedResource > </ Context >
配置连接池
<? xml version='1.0' encoding='utf-8' ?> < Context > < WatchedResource > WEB-INF/web.xml </ WatchedResource > <!-- 配置oracle数据库的连接池 --> < Resource name ="jdbc/oracleds" author ="Container" type ="javax.sql.DataSource" maxActive ="100" maxIdle ="30" maxWait ="10000" username ="scott" password ="tiger" driverClassName ="oracle.jdbc.dirver.OracleDriver" url ="jdbc:oracle:thin:@127.0.0.1:1521:ora9" /> <!-- 配置mysql数据库的连接池, 需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下 maxIdle 连接池中最多可空闲maxIdle个连接 minIdle 连接池中最少空闲maxIdle个连接 initialSize 初始化连接数目 maxWait 连接池中连接用完时,新的请求等待时间,毫秒 username 数据库用户名 password 数据库密码 --> < Resource name ="jdbc/mysqlds" auth ="Container" type ="javax.sql.DataSource" username ="root" password ="root" maxIdle ="30" maxWait ="10000" maxActive ="100" driverClassName ="com.mysql.jdbc.Driver" url ="jdbc:mysql://127.0.0.1:3306/db_blog" /> </ Context >
配置好后需要注意的两个步骤
1. 将对应数据库的驱动类放到 tomcat 的 lib 目录西安
2. 重新启动 tomcat 服务器 , 让配置生效
在 web 应用程序的 web.xml 中设置数据源参考 , 如下:
在 <web-app></web-app> 节点 中加入下面内容
< resource-ref > < description > mysql数据库连接池 </ description > <!-- 参考数据源名字,同Tomcat中配置的Resource节点中name属性值"jdbc/mysqlds"一致 --> < res-ref-name > jdbc/mysqlds </ res-ref-name > <!-- 资源类型 --> < res-type > javax.sql.DataSource </ res-type > < res-auth > Container </ res-auth > < res-sharing-scope > Shareable </ res-sharing-scope > </ resource-ref >
错误解决
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:645) at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:288) at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:325) at javax.naming.InitialContext.lookup(InitialContext.java:392) at com.iblog.util.DBPoolUtil. < clinit > (DBPoolUtil.java:34)
解决方案:
上面的异常信息是配置文件中JNDI没有初始化造成的
如果下面的问题都不存在
1.要去检查下配置文件中连接数据库的URL参数是否正确 2.以及是否导入了正常的包 3.检查在Tomcat中conf/server.xml文件,检查是 否设置useNaming="false",如果是,去掉
2.那就是通过 main方法测试的,这个数据源不支持这样的测试方法,程序要运行在 Tomcat中才能找到相应的数据源 .[我在测试时犯这样的错导致上面错误出现]
< %@ page language ="java" pageEncoding ="UTF-8" contentType ="text/html; charset=UTF-8" % > < %@ page import ="java.sql.*" % > < %@ page import ="javax.naming.*" % > < %@ page import ="javax.sql.DataSource" % > < html > < head > < title > Tomcat6.0 JNDI! </ title > </ head > < body > Tomcat连接池测试,获取数据源 < br > < % try { //初始化查找命名空间 Context ctx = new InitialContext(); //参数java:/comp/env为固定路径 Context envContext = (Context)ctx.lookup("java:/comp/env"); //参数jdbc/mysqlds为数据源和JNDI绑定的名字 DataSource ds = (DataSource)envContext.lookup("jdbc/mysqlds"); Connection conn = ds.getConnection(); conn.close(); out.println("<span style ='color:red;' > JNDI测试成功 < span > "); } catch (NamingException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } %> </ body > </ html >
运行效果:
方法二:在Tomcat的conf/server.xml中配置
打开 tomcat 的 conf/server.xml 文件,找到 <GlobalNamingResources></GlobalNamingResources> 节点 , 默认的内容如下
< GlobalNamingResources > < Resource name ="UserDatabase" auth ="Container" type ="org.apache.catalina.UserDatabase" description ="User database that can be updated and saved" factory ="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname ="conf/tomcat-users.xml" /> </ GlobalNamingResources >
在该节点中加入相关的池配置信息,如下
< GlobalNamingResources > < Resource name ="UserDatabase" auth ="Container" type ="org.apache.catalina.UserDatabase" description ="User database that can be updated and saved" factory ="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname ="conf/tomcat-users.xml" /> <!-- 配置mysql数据库的连接池, 需要做的额外步骤是将mysql的Java驱动类放到tomcat的lib目录下 --> < Resource name ="jdbc/mysqlds" auth ="Container" type ="javax.sql.DataSource" username ="root" password ="root" maxIdle ="30" maxWait ="10000" maxActive ="100" driverClassName ="com.mysql.jdbc.Driver" url ="jdbc:mysql://127.0.0.1:3306/db_blog" /> </ GlobalNamingResources >
在 tomcat 的 conf/context.xml 文件中的 <Context></Context> 节点中加入如下内容
< ResourceLink name ="jdbc/mysqlds" global ="jdbc/mysqlds" type ="javax.sql.DataSource" />
然后在 web 项目中的 WEB-INF 目录下的 web.xml 中配置
< resource-ref > < description > mysql数据库连接池 </ description > <!-- 参考数据源名字,同Tomcat中配置的Resource节点中name属性值"jdbc/mysqlds"一致 --> < res-ref-name > jdbc/mysqlds </ res-ref-name > <!-- 资源类型 --> < res-type > javax.sql.DataSource </ res-type > < res-auth > Container </ res-auth > < res-sharing-scope > Shareable </ res-sharing-scope > </ resource-ref >
同样配置好后,需要重新启动服务器,让配置生效.
方法三:在Tomcat的conf/server.xml中配置虚拟目录时配置
在配置虚拟目录时,也就是在配置 conf 下面的 server.xml 时 , 在 context 标签内 添加池配置 .
在说该方法之前 , 先说一下 , 如何用 tomcat 配置虚拟目录
在 tomcat\conf 下 server.xml 中找到
< Host name ="localhost" appBase ="webapps" unpackWARs ="true" autoDeploy ="true" xmlValidation ="false" xmlNamespaceAware ="false" > </ Host >
在其中添加:
< Context path ="/website" docBase ="F:/myweb" reloadable ="true" ></ Context >
注意 :
docBase 要改成你的项目目录。
path 为虚拟路径 , 访问时的路径,注意 : 一定要加 “/” debug 建议设置为 0
reloadable 设置为 true 。
这样重新启动 tomcat
实例中如下配置
< Context path ="/website" docBase ="D:/program files/Tomcat/apache-tomcat-6.0.33/webapps/iblog.war" reloadable ="true" > </ Context >
接下来添加池配置, 如下
<!-- 配置虚拟目录 --> < Context path ="/website" docBase ="D:/program files/Tomcat/apache-tomcat-6.0.33/webapps/iblog.war" reloadable ="true" > < Resource name ="jdbc/mysqlds" auth ="Container" type ="javax.sql.DataSource" username ="root" password ="root" maxIdle ="30" maxWait ="10000" maxActive ="100" driverClassName ="com.mysql.jdbc.Driver" url ="jdbc:mysql://127.0.0.1:3306/db_blog" /> </ Context >
启动服务器,测试,注意因为我们配置了path值为”/website”,所以访问的路径应该为website.如下图:
方法四:在Web项目中的META-INF目录下新建一个文件context.xml,写入配置
注意:是META-INF目录下,不是WEB-INF目录下
<? xml version='1.0' encoding='utf-8' ?> < Context > < Resource name ="jdbc/mysqlds" auth ="Container" type ="javax.sql.DataSource" username ="root" password ="root" maxIdle ="30" maxWait ="10000" maxActive ="100" driverClassName ="com.mysql.jdbc.Driver" url ="jdbc:mysql://127.0.0.1:3306/db_blog" logAbandoned ="true" /> </ Context >