tomcat数据源原理、配置

1、数据源的作用及操作原理

在程序代码中使用数据源是可以提升操作性能的,这种性能的提升依靠于运行的原理。

传统JDBC操作步骤
    1、加载数据库驱动程序,数据库驱动程序通过CLASSPATH配置;
    2、通过DriverManager类取得数据库连接对象;
    3、通过Connection实例化PreparedStatement对象,编写SQL命令操作数据库;
    4、数据库属于资源操作,操作完成后进行数据库的关闭以释放资源。如图所示:
tomcat数据源原理、配置

对于不同的用户只有操作不同,但是对于1、2、4三个步骤很明显是一个重复的操作。

如果开发中直接使用JDBC操作的话,那么就会产生这种性能的问题,那么怎么做最合适呢?

如果假设数据库不关闭,以后如果有新的用户使用的时候直接取一个已经有的连接的话。

就好比,学校为学生提供雨伞,一旦下雨将为学生准备雨伞,这个时候学生不用再重新去找雨伞,之后再重新去买雨伞。

假设有100把伞,如果现在不下雨,肯定不能把所有的伞都摆上,所以一般平常如果没人用的时候至少摆上10把。当然,最大的时候只能提供100把伞。

还需要一个等待的时间。

最小维持的数据库连接数,最大允许打开的连接数。

Tomcat 4.1 版本之后就开始支持这种操作了,这种操作就称为数据库连接池,存放的是所有的数据库连接。

2、在Tomcat中使用数据库连接池

在web容器中,数据库的连接池都是通过数据源(javax.sql.DataSource)访问的,即:可以通过 javax.sql.DataSource 类取得Connection对象,但是如果要想得到一个DataSource对象需要使用JNDI进行查找。

tomcat数据源原理、配置

JNDI(Java Naming and Directory Interface)属于命名及目录查找接口,主要的功能是用于进行查找的,查找对象。
但是,现在的数据库的连接池是需要在Tomcat上完成配置的。

要修改server.xml文件才可以起作用。

如下,以连接mysql为例:

复制代码
1
2 <Resource name=“jdbc/mydb”
3 auth=“Container”
4 type=“javax.sql.DataSource”
5 maxActive=“100”
6 maxIdle=“30”
7 maxWait=“10000”
8 username=“root”
9 password=“root”
10 driverClassName=“org.gjt.mm.mysql.Driver”
11 url=“jdbc:mysql://localhost:3306/mydb”/>
12

复制代码

此配置有几个参数:
      ·name:表示数据源名称,也是JNDI要查找的名称
      ·auth:表示由谁负责资源连接,Container:容器管理,application:程序管理,一般设置为 Container
      ·type:表示对象,数据源上每一个绑定的都是DataSource
      ·maxActive:表示最大**连接数,这里取值为100,表示同时最多有100个数据库连接,一般把maxActive设置成可能的并发量
      ·maxIdle:表示最大的空闲连接数,这里取值为30,表示即使没有数据库连接时依然可以保持30空闲的连接,而不被清除,随时处于待命状态
      ·maxWait:表示最大等待秒钟数,这里取值10000,表示10秒后超时,如果取值-1,则表示无限等待,直到超时为止,如果超时将接到异常
      ·username:数据库用户名
      ·password:数据库登录密码
      ·driverClassName:数据库驱动名称
      .url:数据库url

但是现在使用的Tomcat版本是6.0以上的版本,所以想让一个数据源起作用的话,还必须在web.xml(注意:此web.xml是web项目的web.xml文件,而不是tomcat服务器的web.xml文件)文件之中完成配置。

1
2 jdbc/mydb
3 javax.sql.DataSource
4 Container
5

3、查找数据源

数据源的操作使用的是JNDI方式进行查找的,所以如果要想使用数据源取得数据库连接的话,则必须按照如下的步骤进行
      初始化名称查找上下文:Context ctx = new InitialContext();
      通过名称查找DataSource对象:DataSource ds = (DataSource)ctx.lookup(JNDI名称);
      通过DataSource取得一个数据库连接:Connection conn = ds.getConnection()。

此时调用数据库会出现一个Exception:
    javax.servlet.ServletException: javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
    实际上对于这种资源操作,本身是需要一个环境属性的支持的: java:comp/env,但是Tomcat服务器本身是免费的,没有对这种属性提供支持,如果要想访问Tomcat中的名称服务的话,则肯定要在前面加上此属性,即,现在的名称是: java:comp/env/jdbc/mydb;即用Tomcat的话JNDI名称就是:java:comp/env/JNDI名称 。

以后程序中只认名字,而具体是哪个数据库将由配置决定。
    当然,如果现在使用的是DAO开发的,DatabaseConnection.java类。

复制代码
1 package com.shawn.mvcdemo.dbc;
2
3 import java.sql.;
4 import javax.sql.
;
5 import javax.naming.*;
6
7 public class DatabaseConnection{
8 private static final String DSNAME = “java:comp/env/jdbc/mldn”;//java:comp/JNDI名称
9
10 private Connection conn = null;
11
12 public DatabaseConnection() throws Exception{
13 Context ctx = new InitialContext();        //初始化名称查找上下文
14 DataSource ds = (DataSource)ctx.lookup(DSNAME); //通过名称查找DataSource对象
15 this.conn = ds.getConnection();          //通过DataSource取得一个数据库连接
16 }
17
18 public Connection getConnection(){
19 return this.conn;
20 }
21
22 public void close() throws Exception{
23 if(this.conn != null){
24 try{
25 this.conn.close();            //释放数据库连接
26 } catch(Exception e){
27 throw e;
28 }
29 }
30 }
31
32 public static void main(String args[]){
33 try{
34 System.out.println(new DatabaseConnection().getConnection());
35 } catch(Exception e){
36 e.printStackTrace();
37 }
38 }
39 }

复制代码

可是有一点也必须注意的是,现在的数据库连接池实在Tomcat上配置的,所以此程序只能在web下运行,而不能使用application程序运行。

总结:

要使用数据库连接池

1、配置server.xml;

2、配置web项目中的(比如:webdemo项目)web.xml文件,添加 resource-ref 配置;

3、修改程序中获取Connection的方式。

配置的三种方式!!!

在我过去工作的过程中,开发用服务器一般都是Tomcat

数据源的配置往往都是在applicationContext.xml中配置一个dataSource的bean

然后在部署时再修改JNDI配置

我猜是因为Tomcat的配置需要改配置文件

不像JBoss,Weblogic等服务器在管理界面可以直接添加JNDI数据源

也很少人去研究它的配置

最近做了个小项目,发布版本的时候都是通过ant编译成jar包之后丢给测试

测试是大爷,教他修改数据源了还是当没听到

周末闲来无聊,看了一些Tomcat配置的教程,下面做一些总结

注:如果你的工程是直接丢在webapps下面的,server.xml中就没有工程对应的Context节点

更新:由于之前有些配置来自网络,不太好用,作了一些更新

对每种方法作了一些个人评价

PS:以下配置在apache-tomcat-6.0.35下测试通过,可以访问数据库

第一种,单个应用独享数据源

就一步,找到Tomcat的server.xml找到工程的Context节点,添加一个私有数据源

Xml代码 收藏代码
1.
2.<Resource
3. name=“jdbc/mysql”
4. scope=“Shareable”
5. type=“javax.sql.DataSource”
6. factory=“org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory”
7. url=“jdbc:mysql://localhost:3306/test”
8. driverClassName =“com.mysql.jdbc.Driver”
9. username=“root”
10. password=“root”
11./>
12.

优点:简单

缺点:重用性差

第二种,配置全局JNDI数据源,应用到单个应用

分两步

第一步, 找到Tomcat的server.xml中GlobalNamingResources节点,在节点下加一个全局数据源

Xml代码 收藏代码
1.<Resource
2. name=“jdbc/mysql”
3. scope=“Shareable”
4. type=“javax.sql.DataSource”
5. factory=“org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory”
6. url=“jdbc:mysql://localhost:3306/test”
7. driverClassName =“com.mysql.jdbc.Driver”
8. username=“root”
9. password=“root”
10./>

第二步,找到要应用此JNDI数据源的工程Context节点,增加对全局数据源的引用ResourceLink

Xml代码 收藏代码
1.
2.
3.

优点:重用性,可控性

缺点:配置相对第三种方法要繁琐一点,每个工程都得配

第三种,配置全局JNDI数据源,应用到所有Tomcat下部署的应用

也分两步

第一步

参考第二种的第一步

第二步,找到Tomcat的context.xml,在Context节点下加一个ResourceLink节点对第一步配置的数据源进行引用

这个XML配置文件的根节点就是

Xml代码 收藏代码
1.
2.
3. WEB-INF/web.xml
4.

优点:重用性,一次性到位

缺点:没有可控性

Spring对JNDI数据源的引用

在applicationContext.xml中加一个bean,替代原来的dataSource

Xml代码 收藏代码
1.<jee:jndi-lookup id=“dataSource” jndi-name=“jdbc/mysql” />

C3P0数据源的配置

type和factory的值发生变化

username=>user

url=>jdbcUrl

driverClassName=>driverClass

Xml代码 收藏代码
1.<Resource name=“jdbc/mysql_c3p0” scope=“Shareable”
2. type=“com.mchange.v2.c3p0.ComboPooledDataSource” ## 标题
3. factory=“org.apache.naming.factory.BeanFactory”
4. jdbcUrl=“jdbc:mysql://localhost:3306/test” driverClass=“com.mysql.jdbc.Driver”
5. user=“root” password=“root” />