一、数据源操作原理
回顾JDBC的操作原理:
(1)加载数据库驱动程序。
(2)通过DriverManager类取得数据库连接对象。
(3)通过Connection实例化PreparedStatement对象,编写SQL语句操作数据库。
(4)数据库属于资源操作,操作完成后要关闭数据库以释放资源。
在使用JDBC连接数据库时,程序会进行多个Socket连接操作,所以这种传统的数据库操作性能是很低的。
那么问题就来了,每个用户进行数据库操作的时候都需要进过相同的(1)、(2)、(4)步骤,但是每个用户对于数据库的操作是不同的,所以在操作数据库时,如果可以将重复的3个步骤去掉,而只是保留步骤(3)的话,性能肯定会有所提高的,这实际上就是数据源产生的原因。
数据源操作的核心原理:在一个对象池中保存多个数据库的链接(也称为数据库连接池,Connection Pool),这样以后再进行数据库操作时,直接从连接池中取出一个数据库连接,当数据库连接操作完成后,再将此连接放回到数据库连接池中,等待其他用户继续使用。
在这之中也会存在几个问题:
- 最小连接数:如果一个程序在使用时没有一个用户连接,则数据库最小应该维持的数据库连接数。
- 最大连接数:在一个程序中一个数据库最多可以打开的数据库连接数。
- 最大等待时间:当一个数据库连接池中已经没有更多的数据库连接提供给用户使用时,其他用户等待的最大时间,如果在等待时间内有连接放回,则可以继续使用;如果超过了最大等待时间,则用户无法取得数据库连接。
这样的程序可以使用Java应用程序来实现,先在一个类集对象中保存多个数据库连接对象,之后通过控制类集达到连接池功能的实现,但是这种实现要考虑多线程的问题,而且以上3中问题也都需要考虑,实现起来比较困难。在Tomcat 4.1.x 版本之后已经支持了此操作,所以,在Web开发中可以直接通过Tomcat即可实现数据库连接池的功能。
数据库连接池组件
如果不适用Tomcat实现数据库连接池,也可以从网上搜索各种数据库连接池的组件进行程序功能的实现,如Apache组织的C3P0组件。
二、在Tomcat中使用数据库连接池
在Web容器中,数据库的链接池都是通过数据源(javax.sql.DataSource)访问的,即通过javax.sql.DataSource类取得一个Connection对象,但是要想得到一个DataSource对象需要使用JNDI进行查找。
Tomcat中的数据源操作JNDI服务
JNDI(Java Naming Directory Interface,Java命名及目录接口)是JavaEE提供的一个服务,其服务的主要功能就是通过一个名称的“Key”查找到对应的一个对象“value”。
客户端通过查询JNDI上所绑定的名称取得一个DataSource对象,并且通过DataSource取得Connection Pool中保存的一个数据连接。
注意:
此时数据源连接池是在Tomcat上进行配置的,所以一定要将数据库的驱动程序复制到%TOMCAT_HOME%\common\lib文件夹中。
在server.xml文件中配置数据库连接池——%TOMCAT_HOME%\conf\server.xml
name属性:指定的是此数据源的名称,这个名称也是以后程序中访问数据库资源时要查找到的名称。
auth属性:表示的是连接数据库的方法,可以有以下两种选项:
- Container:容器将代表应用程序登录到资源管理器,一般使用此方式。
- Application:应用程序必须程序化地登录到资源管理器。
关于数据源的命名规范
在开发中由于可以使用JNDI查询多种资源,为了清晰,在操作数据源中,可以使用jdbc/XXX的命名形式,这样可以直接从命名上知道这是一个操作数据库的命名资源。
server.xml配置完之后就需要在一个web项目中配置web.xml文件,并在文件中指明要使用的数据源名称。
配置web.xml三、查找数据源
数据源的操作使用的是JNDI方式进行查找的,所以如果使用数据源取得数据库连接,则必须按照如下步骤进行:
(1)初始化名称查找上下文:Context ctx = new InitialContext();
(2)通过名称查找DataSource对象:DataSource ds = (DataSource) ctx.lookup(JNDI名称);
(3)通过DataSource取得一个数据库链接:Connection conn = ds.getConnection();
通过数据源取得数据库连接:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="javax.naming.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="java.sql.*"%>
<!DOCTYPE HTML>
<html>
<head>
<title>JSP page</title>
</head>
<body>
<%
String DSNAME = "java:comp/env/jdbc/xxx";
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(DSNAME);
Connection conn = ds.getConnection();
%>
<%=conn%>
<%
conn.close();
%>
</body>
</html>
在server.xml中配置的配置的DataSource名称是“jdbc/XXX”,但是在真正使用的时候却在前面加上一个“java:comp/env/”的前缀,这实际上是java EE规定的一个环境命名上下文,主要是为了解决JNDI查找时的冲突问题。
java:comp/env 环境属性不一定到处都要使用,但是对于Tomcat必须配置,否则无法找到数据源。
在以后的开发中,可以直接将数据源应用到项目中。
package com.meng.dao;
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/xxx";
private Connection conn = null;
public DatabaseConnection() throws Exception {
try {
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(DSNAME);
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;
}
}
}
}
现在的程序只要数据源的名称不变,则数据库可以任意跟换。
网友评论