`

JNDI和数据源在JDBC中的应用

    博客分类:
  • JDBC
阅读更多

      众所周知,JDBC(Java数据库连接)是Java 2企业版的重要组成部分。它是基于SQL层的API。通过把SQL语句嵌入JDBC接口的方法中,用户可以通过Java程序执行几乎所有的数据库操作。JDBC只提供了接口,具体的类的实现要求数据库的设计者完成。通过生成这些接口的实例,即使对于不同的数据库,Java程序也可以正确地执行SQL调用。所以对于程序员来说,不必把注意力放在如何向数据库发送SQL指令,因为程序员需要了解和用到的只是JDBC的接口,只有在极少数情况下会用到面向特定数据库的类,例如程序员希望使用ORACLE的扩展API

      从实际应用的角度出发,我们可以看出采取JDBC直接连接到数据库存在几个问题:

            第一是安全性问题,由于程序代码中包含用户名和密码,其他人如果能得到bytecode,可以通过反编译工具获得用户名和密码。

            第二是代码的可移植性问题。如果希望连接的数据库名称或用户名有所更改,程序员需要修改源程序,然后把修改过的程序发送给用户。也就是说,软件无法脱离数据库独立存在。这样不仅会大大提高软件的成本,也不利于软件本身的发展。

            还可能出现这样的情况:在某些情况下,提供数据的机构不希望数据库的用户名和密码让编写程序的程序员知道知道。这样就提出了一个问题,如何使Java和数据库之间建立连接时隐藏一些敏感的信息。

 

 

数据源(Data Source)及JNDI

  数据源是在JDBC 2.0中引入的一个概念。在JDBC 2.0扩展包中定义了javax.sql.DataSource接口来描述这个概念。如果用户希望建立一个数据库连接,通过查询在JNDI服务中的数据源,可以从数据源中获取相应的数据库连接。这样用户就只需要提供一个逻辑名称(Logic Name),而不是数据库登录的具体细节。

  在这里有必要简单介绍一下JNDI。JNDI 是一种应用程序编程接口 (API) 或库,它为应用程序提供了将名称与对象关联起来以及根据对象的名称在目录中查找对象的方法。JNDI的全称是Java Naming and Directory Interface, 可以理解为Java名称和目录服务接口。JNDI向应用程序提供了一个查询和使用远程服务的机制。这些服务可以是任何企业服务。对于JDBC应用程序来说,JNDI提供的是数据库连接服务。当然JNDI也可以向数据库提供其他服务,但是这超出了本文范围,在此不做论述。

  其实JNDI并不难理解。简单来说,名称服务提供了一个把文件,打印机,服务器等实体映射到一个逻辑名称的机制。例如在操作系统中的名称服务就把打印机映射到一个I/O端口。而目录服务可以理解为名称服务的一个扩展,它允许在服务中的各项拥有自己的属性。又以打印机为例,打印机可以是彩色打印机,支持双面打印,支持网络打印,支持高速打印等。所有这些打印机的属性都可以储存在目录服务中,和相应的打印机联系起来。一些常见的目录服务有NIS,NIS+,LDAP和Novell的NDS等。

  JNDI使应用程序通过使用逻辑名称获取对象和对象提供的服务,从而使程序员可以避免使用与提供对象的机构有关联的代码。例如在下面的例子中使用了在JNDI中的数据源,程序员就不需要提供Oracle8i驱动程序的名称,这样代码的移植能力就更强。

  下面详细介绍一下数据源和javax.sql.DataSource接口。在数据源中存储了所有建立数据库连接的信息。就象通过指定文件名你可以在文件系统中找到文件一样,通过提供正确的数据源名称,你可以找到相应的数据库连接。javax.sql.DataSource接口定义了如何实现数据源。在该接口中定义了九个属性。表一列出了对这些属性的描述。由于本文是以Oracle8i为例,在Oracle8i中没有实现roleName属性,所以在表中没有对此属性做描述。

  表一:数据源标准属性

 

属性名称 属性数据类型 描述
databaseName String 数据库名称,即数据库的SID。
dataSourceName String 数据源接口实现类的名称。
description String 对数据源的描述。
networkProtocol String 和服务器通讯使用的网络协议名。在Oracle8i中,该属性只在使用OCI驱动程序时有效,缺省协议是TCP协议。
password String 用户登录密码。
portNumber Int 数据库服务器使用的端口,缺省值为1521。
serverName String 数据库服务器名称。
user String 用户登录名。


  在javax.sql.DataSource接口中定义了以下方法:

 

* public synchronized void setDatabaseName(String dbname)
* public synchronized String getDatabaseName()
* public synchronized void setDataSourceName(String dsname)
* public synchronized String getDataSourceName()
* public synchronized void setDescription(String desc)
* public synchronized String getDescription()
* public synchronized void setNetworkProtocol(String np)
* public synchronized String getNetworkProtocol()
* public synchronized void setPassword(String pwd)
* public synchronized void setPortNumber(int pn)
* public synchronized int getPortNumber()
* public synchronized void setServerName(String sn)
* public synchronized String getServerName()
* public synchronized void setUser(String user)
* public synchronized String getUser()


  通过这些方法,程序员可以获得建立连接需要的所有信息。需要注意的是,程序员不可以获取登陆密码,这就在一定程度上保证了安全性。需要注意的另一点是所有的方法都是synchronized方法,这是为了保证应用程序的线程安全(Thread-safe)。如果在调用该方法时,即使数据源实例发生变化不会影响程序的正确运行。

  除了实现由SUN定义的属性和方法外,Oracle8i还提供了自己的数据源属性和方法。这些方法和属性是在oracle.jdbc.pool.OracleDataSource中实现的。 Oracle8i扩展数据源属性如表二所示:

  表二:

 

属性名称 属性数据类型 描述
driverType String 使用的Oracle JDBC驱动程序的类型,包括oci8, thin和kprb
url String 数据库连接的URL。
tnsEntry String TNS条目名称


  在oracle.jdbc.pool.OracleDataSource中除了实现javax.sql.DataSource接口中定义的方法外,还实现了以下方法:

 

* public synchronized void setDriverType(String dt)
* public synchronized String getDriverType()
* public synchronized void setURL(String url)
* public synchronized String getURL()
* public synchronized void setTNSEntryName(String tns)
* public synchronized String getTNSEntryName()


  同时,OracleDataSource还实现了java.io.Serializable和javax.naming.Referenceable接口。

  独立使用数据源

  实际应用中,你可以把OracleDataSource注册到JNDI,也可以单独使用。下面先给出一个单独使用OracleDataSource的例子:

 

// 初始化数据源实例
OracleDataSource ods = new OracleDataSource();

ods.setDriverType("thin");
ods.setServerName("Chicago");
ods.setNetworkProtocol("tcp");
ods.setDatabaseName("chidb");
ods.setPortNumber(1521);
ods.setUser("guest");
ods.setPassword("guest");

// 从数据源中获取数据库连接
Connection conn = ods.getConnection();
// 通过数据库连接进行数据操作
   ………………


  使用OracleDataSource时有几点需要注意:

  如果使用的时服务器端内部驱动程序(server-side internal driver),driverType属性会被设置为kprb,其它所有属性失效。

  如果使用Thin或OCI驱动程序:

  URL中可以包括用户登录名和用户登录密码。例如:

jdbc:oracle:thin:guest/guest@Chicago:1521:chidb;

  果设定了url属性,tnsEntry, driverType, portNumber, networkProtocol, serverName,和databaseName属性将失效。

  在没有设定url属性的情况下,如果设定了tnsEntry属性,portNumber, networkProtocol, serverName,和databaseName属性将失效。

  如果使用OCI驱动程序,并且networkProtocol属性被设定为ipc,除user和password外的所有其他属性将失效。

  通过JNDI使用数据源

  在本节首先给出了一个实际程序,然后通过程序来讲解如何通过JNDI查询数据源。

import java.sql.*;
import javax.sql.*;
import oracle.jdbc.driver.*;
import oracle.jdbc.pool.OracleDataSource;
import javax.naming.*;
import javax.naming.spi.*;
import java.util.Hashtable;

public class DataSourceJNDI
{
public static void main (String args [])
throws SQLException
{
// 初始化名称服务环境
Context ctx = null;
try
{
Hashtable env = new Hashtable (5);
env.put (Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put (Context.PROVIDER_URL, "file:JNDI");
ctx = new InitialContext(env);
}
catch (NamingException ne)
{
ne.printStackTrace();
}


bind(ctx, "jdbc/chidb");
lookup(ctx, "jdbc/chidb");

}

static void bind (Context ctx, String ln)
throws NamingException, SQLException
{
// 创建一个OracleDataSource实例
OracleDataSource ods = new OracleDataSource();

ods.setDriverType("thin");
ods.setServerName("Chicago");
ods.setNetworkProtocol("tcp");
ods.setDatabaseName("chidb");
ods.setPortNumber(1521);
ods.setUser("guest");
ods.setPassword("guest");


// 把OracleDataSource实例注册到JNDI中
System.out.println ("Doing a bind with the logical name : " + ln);
ctx.bind (ln,ods);
System.out.println ("Successfully bound");
}

static void lookup (Context ctx, String ln)
throws NamingException, SQLException
{
// 从JNDI中查询OracleDataSource实例
System.out.println ("Doing a lookup with the logical name : " + ln);
OracleDataSource ods = (OracleDataSource) ctx.lookup (ln);
System.out.println ("Successful lookup");

// 从查询到的OracleDataSource实例中获取数据库连接
  Connection conn = ods.getConnection();
  // 进行数据库操作
getUserName(conn);
// 关闭连接
conn.close();
conn = null;
}

static void getUserName(Connection conn)
throws SQLException
{
// 生成一个Statement实例
Statement stmt = conn.createStatement ();

// 从addressbook表中选中姓名列
ResultSet rset = stmt.executeQuery ("select NAME from addressbook");

// 列出addressbook表所有人的姓名
while (rset.next ())
System.out.println ("Name is " + rset.getString (1));

// 关闭RseultSet实例
rset.close();
rset = null;

// 关闭Statement实例
stmt.close();
stmt = null;
}
}

  程序首先生成了一个Context实例。javax.naming.Context接口定义了名称服务环境(Naming Context)及该环境支持的操作。名称服务环境实际上是由名称和对象间的相互映射组成。程序中初始化名称服务环境的环境工厂(Context Factory)是com.sun.jndi.fscontext.RefFSContextFactory(该类在fscontext.jar中可以找到,由于fscontext.jar中包含的不是标准的API,用户需要从www.javasoft.com中的JNDI专区下载一个名为fscontext1_2beta3.zip的压缩文件,在该文件中可以找到fscontext.jar)。环境工厂的作用是生成名称服务环境的实例,javax.naming.spi.InitialContextFactory接口定义了环境工厂应该如何初始化名称服务环境。在初始化名称服务环境时还需要定义环境的URL。程序中使用的是"file:JNDI",也就是把环境保存在本地硬盘的JNDI目录下。

  初始化了名称服务环境后,就可以把数据源实例注册到名称服务环境中。注册时调用javax.naming.Context.bind()方法,参数为注册名称和注册对象。注册成功后,在JNDI目录下会生成一个.binding文件,该文件记录了当前名称服务环境拥有的名称及对象。

  当需要在名称服务环境中查询一个对象时,需要调用javax.naming.Context.lookup()方法,并把查询到的对象显式转化为数据源对象。然后通过该数据源对象进行数据库操作。

  在这个例子中,程序和名称服务环境都是在同一台计算机上运行。在实际的应用中,程序可以通过RMI或CORBA向名称服务环境注册或查询对象。例如在一个服务器-客户机结构中,客户机上的应用程序只需要知道数据源对象在服务器名称服务环境中的逻辑名称,就可以通过RMI向服务器查询数据源,然后通过建立与数据库的连接.这样就可以解决本文最开始提出的问题。

 



 

 

分享到:
评论

相关推荐

    JNDI配置数据源在java web开发中的使用

    在Java Web开发中,JNDI(Java Naming and Directory Interface)是一个重要的标准接口,它允许应用程序查找和使用各种资源,包括数据源(Datasource)。数据源是管理数据库连接的组件,能够有效地处理数据库连接的...

    intellij idea使用tomcat开发时自动部署jndi数据源

    在这个场景中,“intellij idea使用tomcat开发时自动部署jndi数据源”是一个重要的知识点,它涉及到如何在IDE中配置和管理数据库连接,以便于在应用运行时动态地查找和使用数据源。 JNDI(Java Naming and ...

    JNDI数据源【步骤图解】

    总结,JNDI数据源是Java企业级应用中重要的数据库连接管理方式,通过JNDI服务,可以实现数据库连接的集中管理和动态配置,提高应用的可维护性和安全性。理解并正确配置JNDI数据源是开发高效、稳定的Java EE应用的...

    tomcat8 JNDI数据源加密

    TOMCAT8 JNDI对用户名和密码加密

    jndi数据源与数据池

    `jndiDemo`这个文件名可能是指一个演示如何使用JNDI数据源的示例项目,它可能包含一个简单的Java应用,展示了如何在代码中查找和使用数据源。 总之,JNDI数据源和连接池是企业级Java应用中管理数据库连接的标准方法...

    tomcat配置jndi数据源

    Tomcat 中的 JNDI 数据源是指将数据库连接信息注册到 JNDI 服务器中,以便在应用程序中可以通过 JNDI 名称来获取数据库连接。下面我们将详细介绍 Tomcat 配置 JNDI 数据源的多种方式。 方式一:配置单个应用数据源 ...

    tomcat配置JNDI数据源

    【内容】:配置JNDI数据源在Java Web应用程序中是一个重要的任务,它允许应用与数据库之间的连接管理更加高效和集中。在Tomcat服务器上,JNDI(Java Naming and Directory Interface)数据源提供了一种标准的方式来...

    配置 JNDI 数据源

    在Spring框架与Tomcat服务器的集成中,配置JNDI数据源是将数据库连接管理交给服务器来处理,提高应用的可移植性和资源利用率。下面将详细解释配置JNDI数据源的相关知识点。 一、JNDI数据源的概念 JNDI数据源是一种...

    JNDI数据源配置(tomcat)

    在 Tomcat 中,配置 JNDI 数据源有两种方式:单个应用独享数据源和全局 JNDI 数据源。 1. 单个应用独享数据源 在 Tomcat 的 server.xml 文件中,添加一个私有数据源的配置。例如,使用 c3p0 数据源的配置: ```...

    Weblogic JDBC 数据源配置和详细参数说明

    在 BEA WebLogic 8.1 Server 中,配置 JDBC 连接包括创建和配置两个主要的工件——JDBC 连接池和数据源。连接池是数据库连接的一个现存集合,可以在多个活动的 J2EE 应用程序中回收这些数据库连接。数据源是提供对...

    在weblogic 10 中配置jndi数据源

    在WebLogic 10中配置JNDI数据源是一项关键任务,它涉及到应用程序与数据库的连接管理。JNDI(Java Naming and Directory Interface)是一种Java API,用于在分布式环境中查找和绑定各种对象,如数据源、EJB等。在...

    Tomcat jndi 配置数据源过程

    总结,通过上述步骤,你已经在Tomcat中成功配置了一个JNDI数据源,使得应用程序可以通过全局名字方便地获取和释放数据库连接。这种配置方式提高了代码的可复用性和可维护性,同时利用连接池优化了数据库操作的性能。

    Tomcat6+spring+jndi配置数据源说明.docx

    Tomcat6+Spring+JNDI配置数据源说明 本文档主要介绍了Tomcat6+Spring+JNDI配置数据源的详细步骤和原理...本文档提供了详细的 Tomcat6+Spring+JNDI 配置数据源的步骤和原理,可以帮助开发者快速了解和实现数据源配置。

    spring配置JNDI数据源

    总结来说,Spring配置JNDI数据源主要涉及两部分:一是应用服务器中JNDI资源的注册,二是Spring配置文件中通过JNDI查找并使用这些资源。这种方式的好处在于解耦,应用不再直接依赖具体的数据库连接配置,而是通过JNDI...

    jndi数据源的连接方法

    在本教程中,我们将深入探讨如何正确配置和使用JNDI数据源,以及解决配置过程中可能遇到的问题。 首先,理解JNDI数据源的基本概念。JNDI数据源是一个实现了javax.sql.DataSource接口的对象,它负责管理和维护数据库...

    如何在spring中等价配置得到原本由jndi配置实现的数据源

    通常,在Web应用程序中,数据源常常通过Java Naming and Directory Interface (JNDI)进行管理,这允许多个应用共享同一个数据源,例如在应用服务器如Tomcat、JBoss或WebLogic中。然而,有时我们可能希望在非Web环境...

    weblogic下配置JNDI数据源

    WebLogic 下配置 JNDI 数据源 WebLogic 是一款功能强大的 ...配置 JNDI 数据源是 WebLogic 中的一项重要功能,它可以帮助我们实现在 WebLogic 中对数据库和其他资源的访问和管理,提高应用程序的可移植性和灵活性。

    Tomcat-5配置JNDI数据源

    总结,配置Tomcat 5.5及以上版本的JNDI数据源涉及多个步骤,包括添加JDBC驱动、配置全局数据源、在应用中引用数据源以及在代码中通过JNDI查找并使用数据源。选择全局或局部配置取决于应用的需求和资源的共享范围。...

    Tomcat6.0 JNDI数据源经典实例

    总结来说,这个Tomcat 6.0 JNDI数据源经典实例提供了从配置到使用的全过程,包括了必要的文件和脚本,便于开发者理解和实践JNDI数据源在实际项目中的应用。正确配置和使用JNDI数据源能有效管理和优化数据库连接,...

    JNDI数据源配置

    接下来,我们来看一下如何在Tomcat服务器中配置JNDI数据源。 ##### 4.1 配置`web.xml` 首先,在`WEB-INF`目录下的`web.xml`文件中定义数据源引用: ```xml 数据源说明 <res-ref-name>jdbc/AcmeDB <res-type>...

Global site tag (gtag.js) - Google Analytics