原理:
在DataSource中事先建立多个数据库连接,保存在数据库连接池中。当程序访问数据库时,只用从连接池中取空闲状态的数据库连接即可,访问结束,销毁资源,数据库连接重新回到连接池,这与每次去直接访问数据库相比,会节省大量时间和资源。
JNDI( Java Naming and Directory Interface ),是Java平台的一个标准扩展,提供了一组接口、类和关于命名空间的概念。如同其它很多Java技术一样,JDNI是provider-based的技术,暴露了一个 API和一个服务供应接口(SPI)。这意味着任何基于名字的技术都能通过JNDI而提供服务,只要JNDI支持这项技术。JNDI目前所支持的技术包括 LDAP、CORBA Common Object Service(COS)名字服务、RMI、NDS、DNS、Windows注册表等等。很多J2EE技术,包括EJB都依靠JNDI来组织和定位实体。可以把它理解为一种将对象和名字捆绑的技术,对象工厂负责生产出对象,这些对象都和唯一的名字绑在一起,外部资源可以通过名字获得某对象的引用。
在javax.naming的包包中提供Context接口,提供了两个很好用的方法:
<1> void bind( String name , Object object )
将名称绑定到对象。所有中间上下文和目标上下文(由该名称最终原子组件以外的其他所有组件指定)都必须已经存在。
<2>Object lookup( String name )
检索指定的对象。如果 name为空,则返回此上下文的一个新实例(该实例表示与此上下文相同的命名上下文,但其环境可以独立地进行修改,而且可以并发访问)。
运行机制:
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() 方法并没有关闭事实上的数据库连接,仅仅是释 放了被应用程序占用的数据库连接,并将它还给数据库连接缓冲池,数据库连接 缓冲池会自动将这个数据库连接交给请求队列中下一个的应用程序使用。
现在,数据库的连接没有用到连接池几乎很少很少,每个项目组都可能有自己的数据库连接池组件,各容器提供商也提供了各自的数据库连接池,下面介绍一下tomcat的数据库连接管理。
tomcat6 数据源配置(server.xml方式和context.xml方式)
在server.xml下配置你必需重启服务器才能生效,而context.xml配置保存后tomcat会自动加载无需重启
在JNDI配配置数据源中需注意:项目下需要引入数据库驱动包,并且TOMCAT下也需要引入,不然会报错的
1.context.xml方式
Tomcat-6.0.26\conf\context.xml文件当添加以下的配置信息:
<Resource name="jdbc/mysql" 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/sxtele?comautoReconnect=true&failOverReadOnly=false" removeAbandoned="true" removeAbandonedTimeout="60" logAbandoned="true"/>
<Resource name="jdbc/db2" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="60" wait_timeout="18800" timeBetweenEvictionRunsMillis="300000" minEvictableIdleTimeMillis="600000"
username="lcgluser" password="lcgluser" driverClassName="com.ibm.db2.jcc.DB2Driver"
url="jdbc:db2://133.64.46.65:50000/STEDWDB" 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地址
注意,这里你配置的name值要和程序中使用的是一样的,比如按照这个例子,程序就应该是这样的
Java代码
String gENV = "java:comp/env/";
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx .lookup(gENV+"jdbc/mysql");
Connection conn = ds.getConnection();
String gENV = "java:comp/env/";
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup(gENV+"jdbc/db2");
Connection conn = ds.getConnection();
2.在server.xml文件中配置数据源
Tomcat-6.0.26\conf\context.xml中的配置:在<Host></Host>中添加如下配置
<Context path="/sljx" reloadable="true" docBase="sljx" crossContext="true"
debug="0">
<Resource
name="jdbc/oracle"
type="javax.sql.DataSource"
auth="Container"
username="sljx"
password="sljx"
driverClassName="oracle.jdbc.driver.OracleDriver"
maxIdle="3000"
maxWait="5000"
url="jdbc:oracle:thin:@localhost:1521:jadetrus"
autoReconnect="true"
maxActive="1000"/>
</Context>
具体属性解释和JAVA获取数据源跟上面一样
3.在hibernate中配置JNDI也很简单在hibernate.cfg.xml中
<property name="connection.datasource">java:/comp/env/jdbc/mysql</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
常用获取示例
package com.cn.util.db;
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 DBCache {
private InitialContext ic;
private Map<String,DataSource> cache;
private static DBCache instance = new DBCache();
private DBCache() {
try {
ic = new InitialContext();
} catch (NamingException e) {
e.printStackTrace();
}
cache = Collections.synchronizedMap(new HashMap<String,DataSource>());
}
public static DBCache 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 {
if (cache.containsKey(dataSourceName)) {
return cache.get(dataSourceName);
} else {
DataSource newDataSource = (DataSource) ic.lookup(dataSourceName);
cache.put(dataSourceName, newDataSource);
return newDataSource;
}
}
public void removeDateSouceOffCache(String dataSourceName) {
try {
DataSource ds = cache.get(dataSourceName);
ds.getConnection().close();
cache.remove(dataSourceName);
} catch (Exception ex) {
}
}
public static void freeConn(Connection conn) {
freeConn(conn, null, null);
}
public static void freeConn(Connection connection, Statement statement) {
freeConn(connection, statement, null);
}
public static void freeConn(Connection conn, Statement ps, ResultSet rs) {
try {
try {
if (rs != null)
rs.close();
} finally {
try {
if (ps != null)
ps.close();
} finally {
if (conn != null)
conn.close();
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
}
如果获取连接调用getDBConn传入下面两值中任意一个即可
public static final String DATA_SOURCE = "java:comp/env/jdbc/localhostMysql";
public static final String DATA_SOURCE_DB2 = "java:comp/env/jdbc/db2";
private static final String DATA_SOURCE="java:comp/env/jdbc/oracle";
关于JNDI的更多用法
基于JNDI的应用开发
JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名和目录服务的API.命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。
命名或目录服务使你可以集中存储共有信息,这一点在网络应用中是重要的,因为这使得这样的应用更协调、更容易管理。例如,可以将打印机设置存储在目录服务中,以便被与打印机有关的应用使用。
JNDI概述
我们大家每天都不知不觉地使用了命名服务。例如,当你在web浏览器输入URL,http://java.sun.com时,DNS(Domain Name System,域名系统)将这个符号URL名转换成通讯标识(IP地址)。命名系统中的对象可以是DNS记录中的名称、应用服务器中的EJB组件(Enterprise JavaBeans Component)、LDAP(Lightweight Directory Access Protocol)中的用户Profile.
目录服务是命名服务的自然扩展。两者之间的关键差别是目录服务中对象可以有属性(例如,用户有email地址),而命名服务中对象没有属性。因此,在目录服务中,你可以根据属性搜索对象。JNDI允许你访问文件系统中的文件,定位远程RMI注册的对象,访问象LDAP这样的目录服务,定位网络上的EJB组件。
对于象LDAP 客户端、应用launcher、类浏览器、网络管理实用程序,甚至地址薄这样的应用来说,JNDI是一个很好的选择。
JNDI架构
JNDI架构提供了一组标准的独立于命名系统的API,这些API构建在与命名系统有关的驱动之上。这一层有助于将应用与实际数据源分离,因此不管应用访问的是LDAP、RMI、DNS、还是其他的目录服务。换句话说,JNDI独立于目录服务的具体实现,只要你有目录的服务提供接口(或驱动),你就可以使用目录。如图1所示。 图1:JNDI架构
关于JNDI要注意的重要一点是,它提供了应用编程接口(application programming interface,API)和服务提供者接口(service provider interface,SPI)。这一点的真正含义是,要让你的应用与命名服务或目录服务交互,必须有这个服务的JNDI服务提供者,这正是JNDI SPI发挥作用的地方。服务提供者基本上是一组类,这些类为各种具体的命名和目录服务实现了JNDI接口?很象JDBC驱动为各种具体的数据库系统实现了JDBC接口一样。作为一个应用开发者,你不必操心JNDI SPI.你只需要确认你要使用的每一个命名或目录服务都有服务提供者。
J2SE和JNDI
Java 2 SDK 1.3及以上的版本包含了JNDI.对于JDK 1.1和1.2也有一个标准的扩展。Java 2 SDK 1.4.x的最新版本包括了几个增强和下面的命名/目录服务提供者:
l LDAP(Lightweight Directory Access Protocol)服务提供者 l CORBA COS(Common Object Request Broker Architecture Common Object Services)命名服务提供者 l RMI(Java Remote Method Invocation)注册服务提供者 l DNS(Domain Name System)服务提供者
更多的服务提供者
可以在如下网址找到可以下载的服务提供者列表:
http://java.sun.com/products/jndi/serviceproviders.html 特别有意思的或许是如下网址提供的Windows 注册表JNDI服务提供者:http://cogentlogic.com/cocoon/CogentLogicCorporation/JNDI.xml 这个服务提供者使你可以访问Windows XP/2000/NT/Me/9x的windows注册表。
也可以在如下网址下载JNDI/LDAP Booster Pack:http://java.sun.com/products/jndi/ 这个Booster Pack包含了对流行的LDAP<span s
分享到:
相关推荐
SQL Server是由微软公司提供的一个全面的数据库平台。配置SQL Server数据库的JNDI时,需要指定: - **Driver Class**:`com.microsoft.jdbc.sqlserver.SQLServerDriver` - **URL**:`jdbc:microsoft:sqlserver://...
JAVA笔试总结 非常全面 基本上囊括了Java所有常考知识点,并且每个知识点都有详细解释。 知识点主要包括: native,transient,volatile,strictfp,CMM,synchronized,java socket,压缩与解压缩,多线程,垃圾回收算法,...
然而,网络上关于JAVA对Oracle中BLOB、CLOB类型字段的操作说明往往不够全面、不够准确,甚至有的简直就是胡说八道。因此,本文旨在总结JAVA对Oracle中BLOB、CLOB类型字段的操作,包括入库和出库操作的实现细节。 一...
6. **JNDI(Java Naming and Directory Interface)**:JNDI提供了一种查找和绑定资源的接口,常用于服务定位和服务注册,如数据源、邮件服务器等。 7. **JTA(Java Transaction API)**:JTA是处理分布式事务的...
#### 七、总结 J2EE系统为企业级应用程序的开发提供了强大的支持,通过深入理解其核心概念和技术细节,初学者可以更加高效地构建高质量的应用程序。在未来的学习过程中,建议结合实际项目经验,逐步掌握并灵活运用...
总结起来,Log4j2 2.15.0通过默认禁用JNDI查找和增加安全限制等方式,有效地解决了“Log4Shell”漏洞。然而,安全是一个持续的过程,开发者需要时刻保持警惕,不断更新和优化安全策略,以应对不断演变的威胁。只有...
WebLogic是Oracle公司开发的一款企业级应用服务器,它提供了用于构建、部署和管理企业应用程序的全面平台。在本配置中,WebLogic主要用于运行和管理基于Java EE(Java Platform, Enterprise Edition)的应用程序。...
本篇内容将深入探讨JDBC连接的各个方面,旨在为你提供全面的理解和实用技巧。 ### 1. JDBC基础知识 - **JDBC API**: 包含一系列的接口和类,如`java.sql.DriverManager`, `java.sql.Connection`, `java.sql....
而Hibernate则提供了更全面的对象关系映射,自动处理了大部分的数据库交互,但可能会牺牲一些性能。在选择时,需要权衡灵活性、性能和自动化程度。 **4. 项目实战:“移动商城”(四)** 这部分内容可能是讲解如何...
### J2EE课程总结 #### 数据库:Oracle **1. Oracle SQL基础知识** - **选择行**:通过`SELECT`语句结合`WHERE`子句来实现特定条件下的数据筛选。 - **限制选择行**:利用`LIMIT`或`ROWNUM`来限制返回结果的数量...
总的来说,Java EE提供了全面的工具和框架,以适应企业级开发的需求,从基础服务到高级框架,都体现了Java在构建可扩展、可维护和高性能应用程序方面的强大能力。通过深入学习和实践Java EE,开发者不仅可以提升自己...
总结来说,JavaEE是构建企业级应用的强大工具,它涵盖了一系列技术,从基础服务到高级框架,为开发者提供了全面的解决方案。通过学习和实践,我们可以掌握这些技术,从而更高效地开发和维护复杂的业务系统。在互联网...
总结:JBoss开发人员指南旨在帮助开发者掌握JBoss的各项核心功能,从安装部署到应用开发、性能优化,全面解析JBoss的使用和管理,为构建稳定、高效的企业级应用提供有力支持。通过深入学习和实践,开发者将能够充分...
总结来说,J2EE是一个强大且全面的企业级应用开发框架,它通过标准化的API、组件模型和集成策略,帮助企业构建稳定、高效、可维护的分布式系统。无论是在遗留系统整合、快速开发还是在大型企业环境中,J2EE都能提供...
总结,配置JBoss以支持EJB2.0和EJB3.0的服务涉及多个层面,包括EJB组件定义、数据源配置、JNDI名称设定以及注解驱动的编程模式。了解和掌握这些配置知识对于在JBoss环境下开发和部署Java企业应用至关重要。
### J2EE全面简介 #### 一、J2EE概念 Java 2 Platform, Enterprise Edition (J2EE) 是一种企业级应用开发平台标准,它基于 Java 语言,并且为开发分布式多层 Web 应用提供了强大的支持。J2EE 的主要目标是使企业级...
本文将深入解析连接池操作的核心概念、配置方法以及其实现细节,旨在为开发者提供全面的理解与实践指导。 ### 连接池基本概念 连接池,顾名思义,就是一种管理并复用数据库连接的技术。它预先创建一定数量的数据库...
本篇将基于"最新JAVA面试题总结之框架.zip"的内容,深入探讨Java面试中常涉及的框架相关知识点。 1. **Spring框架** Spring是Java企业级应用的事实标准,它提供了全面的应用服务,包括依赖注入(DI)、面向切面...
它是一个基于Java技术的、开放的、可移植的、标准的、多层架构的软件平台,为开发和部署在互联网上的复杂企业应用程序提供了全面的解决方案。 J2EE的核心理念是组件化开发,通过提供一系列的标准接口和服务,使得...