Tomcat数据源

一.数据库操作原理

首先,先来回顾一下JDBC操作原理:

1.加载数据库驱动程序,数据库驱动程序通过classpath配置。

2.通过DriverManager类取得数据库连接对象。

3.通过Connection实例化PreparedStatement对象,编写SQL命令操作数据库。

4.数据库属于资源操作,操作完成后要关闭数据库以释放资源。


注:数据库连接时需要建立多次连接:在使用JDBC连接数据库时,程序会进行多个socket连接操作,所以这种传统的数据库操作性能是很低的。

   由于每一个用户进行数据库操作时都会经过上面的三个步骤(1、2、4),但是每个用户对于数据库的操作却是不同的,例如,有的时更新数据库,有的是查询数据库,所以在进行数据库操作时,如果可以省略掉其中重复的三个步骤,只保留步骤3的话,那么性能肯定会有所提高,这实际上就是数据源产生的原因。

    数据源操作的核心就是,在一个对象池中保存多个数据库连接(也称为数据库连接池,Connection Pool),这样以后再进行数据库操作时,直接从连接池中取出一条连接,当数据库操作完成之后,再将此连接放回到数据库连接池中,等待其他用户继续使用。这就好比现在的共享单车,一个地区放置的单车数量是有限的,当我们要使用,直接扫码开锁使用就行,当我们使用完则关锁付车费就行,而当车辆都在使用,我们要骑车只能等待别人使用完才行。

    数据源中有以下几个元素:

(1)最小连接数:如果一个程序在使用时没有一个用户连接,则数据库最小应该维持的数据库连接数。

(2)最大连接数:在一个程序中一个数据库最多可以打开的数据库连接数。

(3)最大等待时间:当一个数据库连接池已经没有空闲数据库连接提供给用户使用时,其他用户等待的最大时间,如果在等待时间内有连接空闲出来,则可以继续使用;如果超过了最大等待时间,则用户无法取得数据库连接。

    这样的程序可以使用java应用程序来实现,先在一个类集中保存多个数据库连接对象,之后通过控制类集达到连接池功能的实现,但是这种实现要考虑多线程的问题,而且以上三种问题也需要考虑,实现起来比较困难,而幸运的是在Tomcat4.1x版本之后已经支持了此操作,所以,在web开发中可以直接通过Tomcat即可实现数据库连接池的功能。

数据库连接池组件:如果不使用Tomcat实现数据库连接池,也可以从网上搜索各种数据库连接池的组件进行程序功能的实现,如Apache组织的C3P0组件。

二.在Tomcat中使用数据库连接池

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

JNDI服务:

    JNDI(Java Naming and Directory Interface,java命名及目录接口)是javaEE提供的一个服务,其服务的主要功能就是通过一个名称“key”查找到对应的一个对象“value”,这一设计也体现出了java程序的设计理念,通过key对应value,只要key不改变,则value可以随意修改。


从图中可以发现,客户端通过查询JNDI上绑定的名称取得一个DataSource对象,并且通过DataSource取得Connection Pool中保存的一个数据库连接。

注:此时的数据源连接池是在Tomcat上进行配置的,所以一定要将数据库的驱动程序复制到%TOMCAT_HOME%\common\lib文件夹中。

在server.xml文件中配置数据库连接池——%TOMCAT_HOME%\conf\server.xml

		<Context docBase="D:\apache_tomcat\apache-tomcat-9.0.1\webapps\shop1" path="/" reloadable="true">
			<Resource name="jdbc/mydb"	->配置一个数据库连接池资源,名称为jdbc/mydb		
				auth="Container"	->容器负责资源连接	
				type="javax.sql.DataSource"    ->此数据源名称对应的类型为DataSource		
				maxActive="100"		       ->可以打开的最大连接数
				maxIdle="30"		       ->维持的最小连接数
				maxWait="10000"		       ->用户等待的最大时间
				username="root"		       ->数据库用户名
				password="111111"	       ->数据库密码
				driverClassName="org.gjt.mm.mysql.Driver"	->数据库驱动程序
				url="jdbc:mysql://localhost:3306/loginmanage"   ->数据库名称
			/>
		</Context>

注:以上的注释只是为了说明各各项,具体使用时必须删除。另外,docBase的路径必须是一个web项目的路径。

以上的配置在<Context>节点中增加了一个<Resource>节点,用来表示配置的连接池选项,其中name属性指定的是此数据源的名称,此处为“jdbc/mydb”,这个名称也是以后程序中访问数据库资源时要查找的名称。

在<Resource>节点中的auth选项表示的是连接数据库的方法,可以有以下两种选择:

Container:容器将代表应用程序登录到资源管理器,一般使用此方式。

Application:应用程序必须程序化地登录到资源管理器。

提示:关于数据源名称地命名规范==》在开发中由于可以使用JNDI查询多种资源,为了清晰,在操作用于访问数据库的数据源中,可以使用jdbc/XXX的命名形式,这样可以直接从命名上知道这是一个操作数据库的命名资源。

上面配置的MySql数据库的驱动程序,如果要使用Oracle,则只需要替换相关的属性内容即可。

		<Context docBase="D:\apache_tomcat\apache-tomcat-9.0.1\webapps\shop1" path="/" reloadable="true">
			<Resource name="jdbc/mydb"	->配置一个数据库连接池资源,名称为jdbc/mydb		
				auth="Container"	->容器负责资源连接	
				type="javax.sql.DataSource"    ->此数据源名称对应的类型为DataSource		
				maxActive="100"		       ->可以打开的最大连接数
				maxIdle="30"		       ->维持的最小连接数
				maxWait="10000"		       ->用户等待的最大时间
				username="root"		       ->数据库用户名
				password="111111"	       ->数据库密码
				driverClassName="oracle.jdbc.driver.OracleDriver"	->数据库驱动程序
				url="jdbc:oracle:thin:@localhost:1521:loginmanage"   ->数据库名称
			/>
		</Context>

server.xml配置完成后就需要在一个web项目中配置web.xml文件,并在文件中指明要使用的数据源名称:

  <resource-ref>
  	<description>DB Connection</description>
  	<res-ref-name>jdbc/mydb</res-ref-name>
  	<res-type>javax.sql.DataSource</res-type>
  	<res-auth>Container</res-auth>
  </resource-ref>

三.查找数据源

数据源使用JNDI方式进行查找,所以如果使用数据源取得数据库连接,则必须按照以下步骤进行:

1.初始化名称查找上下文:Context ctx=new InitialContext();

2.通过名称查找DataSource(数据源)对象:DataSource ds=(DataSource)cxt.lookup(JNDI名称);

3.通过DataSource取得一个数据库连接:Connection conn=ds.getConnection();

示例:通过数据源取得数据库连接——datasource.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="javax.naming.*,
				 javax.sql.*,
				 java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>通过数据源取得数据库连接</title>
</head>
<body>
	<%
		String DSNAME="java:comp/env/jdbc/mydb";	//JNDI名称
		Context cxt=new InitialContext();			//初始化名称查找上下文
		DataSource ds=(DataSource)cxt.lookup(DSNAME);//取得DataBase的实例
		Connection conn=ds.getConnection();			//取得数据库连接
	%>
		<%=conn %>
	<%
		conn.close();	//将数据库连接直接放回池中去
	%>
</body>
</html>

在本程序中可以发现,虽然真正在server.xml中配置的DataSource名称是“jdbc/mydb”,但是真正使用时却在前面加上了一个“java:comp/env/”前缀,这实际上是javaEE规定的一个环境命名上下文(Environment Naming Context (ENC)),主要是为了解决JNDI查找时的冲突问题。

注:java:comp/env/环境属性不一定到处都要使用==》对于一些高级服务器(如WebLogic、Websphere)由于本身已经设置好了此属性,所以在进行数据源查找时可以不用设置此属性,但是对于Tomcat必须设置,否则无法找到。

上面的程序直接打印出Connection对象,如果可以取得连接,则会输出一个对象信息;如果没有取得连接,则打印null。

在以后的开发中,就可以直接将数据源应用到项目中,例如,在DAO开发中经常使用到的DatabaseConnection类,就可以将其替换成数据源连接。

修改DAO中的DatabaseConnection.java:

package com.test;

import java.sql.Connection;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;




public class DatabaseConnection {
	//定义JNDI的查找名称
	private static final String DSNAME="java:comp/env/jdbc/mydb";
	private Connection conn=null;
	public DatabaseConnection()throws Exception{//在构造方法中进行数据库连接
		try {
			Context cxt=new InitialContext();//初始化名称查找上下文
			DataSource ds=(DataSource)cxt.lookup(DSNAME);//取得DataSource的实例
			this.conn=ds.getConnection();//取得数据库连接
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public Connection getConnection() {//取得数据库连接
		return this.conn;
	}
	
	public void close()throws Exception{//数据库关闭操作
		if(this.conn!=null) {	//避免空指向异常
			try {
				this.conn.close();		//数据库关闭
			}catch(Exception e) {		//抛出异常
				throw e;
			}
		}
	}
}
现在的程序只要数据源的名称不变,则数据库可以任意变换,这也充分体现了java的设计思想——可移植性。

                
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值