JNDI原理:
jndi是Java 命名和目录接口(Java Naming and Directory Interface,JNDI)的简称.从一开始就一直是 Java 2平台企业版的核心技术之一。在JMS,JMail,JDBC,EJB等技术中,就大量应用的这种技术。JNDI可访问的现有的目录及服务有:DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol 轻型目录访问协议)、 CORBA对象服务、文件系统、Windows XP/2000/NT/Me/9x的注册表、RMI、DSML v1&v2、NIS。
jndi典型的运用场景:数据源,tomcat中配置一个数据源,程序就可以通过java.sql接口去访问数据库,不管底层的数据库是什么类型。
同样的在DataSource中事先建立多个数据库连接,保存在数据库连接池中。当程序访问数据库时,只用从连接池中取空闲状态的数据库连接即可,访问结束,销毁资源,数据库连接重新回到连接池,这与每次去直接访问数据库相比,会节省大量时间和资源。
Jndi运行机制:
1、 首先程序代码获取初始化的 JNDI 环境并且调用 Context.lookup() 方法从 JNDI 服务提供者那里获一个 DataSource 对象
2、 中间层 JNDI 服务提供者返回一个 DataSource 对象给当前的 Java 应用程序这个 DataSource 对象代表了中间层服务上现存的缓冲数据源
3、 应用程序调用 DataSource 对象的 getConnection() 方法
4、 当 DataSource 对象的 getConnection() 方法被调用时,中间层服务器将查询数据库 连接缓冲池中有没有 PooledConnection 接口的实例对象。这个 PooledConnection 对象将被用于与数据库建立物理上的数据库连接
5、 如果在缓冲池中命中了一个 PooledCoonection 对象那么连接缓冲池将简单地更 新内部的缓冲连接队列并将该 PooledConnection 对象返回。如果在缓冲池内没 有找到现成的 PooledConnection 对象,那么 ConnectionPoolDataSource 接口将会被 用来产生一个新的 PooledConnection 对象并将它返回以便应用程序使用
6、 中间层服务器调用 PooledConnection 对象的 getConnection() 方法以便返还一个 java.sql.Connection 对象给当前的 Java 应用程序
7、 当中间层服务器调用 PooledConnection 对象的 getConnection() 方法时, JDBC 数据 库驱动程序将会创建一个 Connection 对象并且把它返回中间层服务器
8、 中间层服务器将 Connection 对象返回给应用程序 Java 应用程序,可以认为这个 Connection 对象是一个普通的 JDBC Connection 对象使用它可以和数据库建立。事 实上的连接与数据库引擎产生交互操作 。
9、 当应用程序不需要使用 Connection 对象时,可以调用 Connection 接口的 close() 方 法。请注意这种情况下 close() 方法并没有关闭事实上的数据库连接,仅仅是释 放了被应用程序占用的数据库连接,并将它还给数据库连接缓冲池,数据库连接缓冲池会自动将这个数据库连接交给请求队列中下一个的应用程序使用。
tomcat6 数据源配置(server.xml方式和context.xml方式)
在server.xml下配置你必需重启服务器才能生效,而context.xml配置保存后tomcat会自动加载无需重启,在JNDI配配置数据源中需注意:项目下需要引入数据库的jdbc驱动包,并且TOMCAT下也需要引入,不然会报错的,意思就是需要把 mysql jdbc driver的jar包拷贝到tomcat/lib目录下,如本例需要把mysql-connector-java-5.1.18.jar拷贝到tomcat的lib目录下
1. tomcat的context.xml配置数据源方式
首先在Tomcat\conf\context.xml文件中添加以下的配置信息:
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="60"
wait_timeout="18800"
timeBetweenEvictionRunsMillis="300000"
minEvictableIdleTimeMillis="600000"
username="root"
password="jdzxdb"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8"
removeAbandoned="true"
removeAbandonedTimeout="60"
logAbandoned="true"/>
其中:
name 表示指定的jndi名称
auth 表示认证方式,一般为Container
type 表示数据源床型,使用标准的javax.sql.DataSource
maxActive 表示连接池当中最大的数据库连接
maxIdle 表示最大的空闲连接数
maxWait 当池的数据库连接已经被占用的时候,最大等待时间
logAbandoned 表示被丢弃的数据库连接是否做记录,以便跟踪
username 表示数据库用户名
password 表示数据库用户的密码
driverClassName 表示JDBC DRIVER
url 表示数据库URL地址
//tomcat中使用的时候需要添加java:comp/env/
String prefix = "java:comp/env/";
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx .lookup(ctx+"jdbc/mysql");
Connection conn = ds.getConnection();
2.在server.xml文件中配置数据源
Tomcat\conf\server.xml中的配置:在中添加如下配置
crossContext="true" debug="0">
name="jdbc/mysql"
type="javax.sql.DataSource"
auth="Container"
username="root"
password="root"
driverClassName="oracle.jdbc.driver.OracleDriver"
maxIdle="10"
maxWait="10"
url="jdbc:oracle:thin:@localhost:1521:orcl"
maxActive="50"/>
3.在hibernate中配置JNDI也很简单在hibernate.cfg.xml中
java:/comp/env/jdbc/mysql
org.hibernate.dialect.MySQLDialect
4.在spring中配置JNDI也很简单
class="org.springframework.jndi.JndiObjectFactoryBean">
java:comp/env/jdbc/Mysqlserver
常用获取jndi示例
package com;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DbUtils {
private InitialContext initContext;
private static DbUtils instance = new DbUtils();
private DbUtils() {
try {
initContext = new InitialContext();
} catch (NamingException e) {
e.printStackTrace();
}
}
public static DbUtils getInstance() {
return instance;
}
public Connection getDBConn(String dataSourceName) throws SQLException,
NamingException {
Connection conn = null;
conn=getDataSource(dataSourceName).getConnection();
return conn;
}
public DataSource getDataSource(String dataSourceName)
throws NamingException {
DataSource newDataSource = (DataSource) initContext.lookup(dataSourceName);
return newDataSource;
}
public void close(Connection conn,Statement stmt,ResultSet rs) {
try{
if(rs!=null){
rs.close();
}
rs=null;
}catch(SQLException ex){
ex.printStackTrace();
}
try{
if(stmt!=null){
stmt.close();
}
stmt=null;
}catch(SQLException ex) {
ex.printStackTrace();
}
try{
if(conn!=null){
conn.close();
}
conn=null;
}catch(SQLException ex) {
ex.printStackTrace();
}
}
}
tomcat如果获取连接调用getDBConn传入下面两值中任意一个即可
public static final String DS_MYSQL = "java:comp/env/jdbc/mysql";
public static final String DS_DB2= "java:comp/env/jdbc/db2";
public static final String DS_ORACLE="java:comp/env/jdbc/oracle";