文章目录
背景
使用JDBC问题
- 数据库服务器名称MyDBServer 、用户名和口令都可能需要改变,由此引发JDBC URL需要修改。
- 数据库可能改用别的产品,如改用DB2或者Oracle,引发JDBC驱动程序包和类名需要修改。
- 随着实际使用终端的增加,原配置的连接池参数可能需要调整。
定义
JNDI(Java Naming And Directory Interface)
-
是Java命名和目录接口的简称,是J2EE规范的核心技术之一。在JMS、JMail、JDBC、EJB等技术中都大量应用了JNDI技术。
-
JNDI提供了一种服务,这个服务可以将“名称”和“资源”进行绑定,然后程序员通过面向JNDI接口调用方法lookup可以查找到相关的资源。
-
它提供客户端接口api,可以使开发者不必关心数据库的username、password、driver是什么,而是通过API接口直接调用,使用xml配置服务器全局共用的数据源。它只是接口规范,具体由服务器来实现。比如:使用tomcat就由tomcat来实现这个接口,使用jboss就由jboss来实现这个接口。
优点
- 降低程序和程序之间的耦合性。
- 降低设备和设备的耦合性。
关系
JNDI是一个树结构,树上绑定了很多dataSource,这些dataSource用来和连接池交互,可以理解为Connection pool的上层结构。Connection pool则用来维护管理固定数量的连接,直接和db层进行操作。
Context接口
是命名服务的核心接口,提供对象查找、绑定/解除绑定、重命名对象、创建和销毁子上下文等操作。
InitialContext类
实现了Context接口,是访问命名服务的起始上下文,通过它可以查找对象和子上下文。
在J2EE容器中配置JNDI参数,定义一个数据源,也就是JDBC引用参数,给这个数据源设置一个名称;然后,在程序中,通过数据源名称引用数据源从而访问后台数据库。
tomcat配置JNDI
第一步:配置tomcat的conf文件下面的context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Resource name="jdbc/fov" auth="Container" type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="root"
password="666666"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/bookdb" />
</Context>
第二步:把驱动jar包放到common的lib下面
第三步:配置tomcat的conf文件下面的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<resource-ref>
<description>news DataSource</description>
<res-ref-name>jdbc/fov</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
#数据库驱动
driverClassName=com.mysql.jdbc.Driver
#数据库连接地址
url=jdbc:mysql://localhost/test
#用户名
username=root
#密码
password=123456
#连接池的最大数据库连接数。设为0表示无限制
maxActive=30
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为0表示无限制
maxIdle=10
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制
maxWait=1000
#超过removeAbandonedTimeout时间后,是否进行没用连接(废弃)的回收(默认为false,调整为true)
removeAbandoned=true
#超过时间限制,回收没有用(废弃)的连接(默认为 300秒)
removeAbandonedTimeout=180
第四步:调用
单例模式实现连接对象的创建
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
public class ConnectionFactory {
private static ConnectionFactory aFactorySingleton;
private Context ctx;
private ConnectionFactory() throws NamingException {
ctx = new InitialContext();
}
public static synchronized ConnectionFactory getInstance() throws SQLException {
try {
if (aFactorySingleton == null) {
aFactorySingleton = new ConnectionFactory();
}
} catch (NamingException e) {
throw new SQLException(e.toString());
}
return aFactorySingleton;
}
public Connection getConnection(String jndiName) throws SQLException {
try {
return this.getDataSource(jndiName).getConnection();
} catch (NamingException e) {
throw new SQLException(e.toString());
}
}
private DataSource getDataSource(String jndiName) throws NamingException {
DataSource ds = (DataSource) ctx.lookup(jndiName);
return ds;
}
}
JNDI NAME要在前面加上"java:comp/env/"
/*
* tomcat通过jndi访问数据库
*/
public class ConDBTool {
public Connection getConnection(){
Connection con=null;
try {
con = ConnectionFactory.getFactory().getConnection("java:comp/env/jdbc/fov");
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
}