jdbc 和 jndi 的关系

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:  Java Database Connectivity(JDBC)JDBC以一种统一的方式来对各种各样的数据库进行存取。和ODBC一样,JDBC为开发人员隐藏了不同数据库的不同特性。

 Java Database Connectivity(JDBC)JDBC以一种统一的方式来对各种各样的数据库进行存取。和ODBC一样,JDBC为开发人员隐藏了不同数据库的不同特性。另外,由于JDBC建立在Java的基础上,因此还提供了数据库存取的平台独立性。JDBC定义了4种不同的驱动程序:JDBC-ODBCBridgeJDBC-native driverbridgeJDBC-networkbridgePureJavadriver。在一个多层的企业级应用中,更大的可能是在客户端和一个EJB进行通信,采用EJB建立数据库连接。为了实现和改进可伸缩性和系统性能, 也可以采用连接缓冲池(connection pool)优化数据库连接。

Java Naming and Directory Interface (JNDI)JNDI API被用于执行名字和目录服务。它提供了一致的模型来存取和操作企业级的资源如DNSLDAP,本地文件系统,后者在应用服务器中的对象。JNDI中,在目录结构中的每一个结点称为context。每一个JNDI名字都是相对于context的。应用可以通过这个初始化的context经有这个目录树来定位它所需要的资源或对象。(这句话什么意思呢?是这样的:

JNDI 对应于J2SE中的javax.naming包,这套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需通过名称检索即可。 

其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

JNDI的结构:
JNDI的结构自上而下包含3个主要层次:
1)应用层:该层使用JNDI API
2)JNDI API层:该层定义一组类和接口,可以用来访问任何命名或目录服务。
   JNDI类库包含在 java2 SDK中,主要包含如下程序包:

1、用于命名操作的javax.naming;
2、用于目录操作的javax.naming.directory
3、在命名和目录服务器中请求事件通知的javax.naming.event;
4、提供LDAP支持的javax.naming.ldap
3)实现层:该层为JNDI SPI API及其具体实现,它包括以下几个命名/目录服务器提供者:LDAP,CORBA,RMI,DNS等。


JNDI命名与上下文:
  JNDI命名服务对象映射为名称,这种映射可以获得远程对象的引用,以及调用远程对象的方法,而不必知道该对象在网络上的物理地址。可以使用javax.naming程序包来访问JNDI命名服务,这个程序包包括如下命名方法: 获得初始上下文,把对象绑定到名称上,查找对象等。


 在命名系统中,上下文作为查找对象过程的起点。在文件系统中,每个目录都可以看做是一个上下文。JNDI API定义了Context接口,该接口在JNDI中起着重要作用。JNDI还定义了InitialContext类,要执行任何操作,必须建立一个InitialContext。


JNDI相对与JDBC来说是他的灵活性,程序员不需要关心“具体的数据库后台是什么?JDBC驱动程序是什么?JDBC URL格式是什么?访问数据库的用户名和口令是什么?”等等这些问题,程序员编写的程序应该没有对 JDBC 驱动程序的引用,没有服务器名称,没有用户名称或口令 —— 甚至没有数据库池或连接管理。而是把这些问题交给J2EE容器来配置和管理(比如weblogic),程序员只需要对这些配置和管理进行引用即可。

理解连接池

连接池技术能显著增加Java应用程序的性能,同时还能降低资源使用率。连接池技术的主要优点包括:

·         缩短了连接创建时间

与其他数据库相比,MySQL提供了快速的连接设置功能,连接时间通常不是问题,但创建新的JDBC连接仍会导致联网操作和一定的IDBC驱动开销,如果这类连接是“循环”使用的,使用该方式,可避免这类不利因素。

·         简化的编程模型

使用连接池技术时,每个单独线程能够像创建了自己的JDBC连接那样进行操作,从而允许使用直接的JDBC编程技术。

·         受控的资源使用

如果不使用连接池技术,而是在每次需要时为线程创建新的连接,那么应用程序的资源使用将十分浪费,而且在负载较重的情况下会导致无法预期的结果。连接池能够使性能最大化,同时还能将资源利用控制在一定的水平之下,如果超过该水平,应用程序将崩溃而不仅仅是变慢。

幸运的是,Sun公司通过JDBC-2.0“可选”接口,完成了JDBC中连接池概念的标准化实施,所有主要应用服务器均实施了能够与MySQL Connector/J一起良好工作的这类API

通常,你可以在应用服务器的配置文件中配置连接池,并通过Java命名和目录接口(JNDI)访问它。在下面的代码中,介绍了在J2E应用服务器上运行的应用程序中使用连接池的方法:

示例26.12. J2EE应用服务器一起使用连接池

import java.sql.Connection;

import java.sql.SQLException;

import java.sql.Statement;

import javax.naming.InitialContext;

import javax.sql.DataSource;

public class MyServletJspOrEjb {

    public void doSomething() throws Exception {

        /*

         * Create a JNDI Initial context to be able to  lookup the DataSource

         *

         * In production-level code, this should be cached as  an instance or static variable, as it can  be quite expensive 

         * to create a JNDI context.(创建一个JNDI context是非常昂贵的资源耗费)

         *

         * Note: This code only works when you are using servlets or EJBs in a J2EE application server. If you are

         * using connection pooling in standalone Java code, you will have to create/configure datasources using whatever

         * mechanisms your particular connection pooling library  provides.

         */

        InitialContext ctx = new InitialContext();

         /*

          * Lookup the DataSource, which will be backed by a pool that the application server provides. DataSource instances

          * are also a good candidate for caching as an instance variable, as JNDI lookups can be expensive as well.

          */

        DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/MySQLDB");

        /*

         * The following code is what would actually be in your  Servlet, JSP or EJB 'service' method...where you need

         * to work with a JDBC connection.

         */

        Connection conn = null;

        Statement stmt = null;

        try {

            conn = ds.getConnection();

            /*

             * Now, use normal JDBC programming to work with MySQL, making sure to close each resource when you're

             * finished with it, which allows the connection pool  resources to be recovered as quickly as possible

             */

            stmt = conn.createStatement();

            stmt.execute("SOME SQL QUERY");

            stmt.close();

            stmt = null;

            conn.close();

            conn = null;

        } finally {

            /*

             * close any jdbc instances here that weren't explicitly closed during normal code path, so

             * that we don't 'leak' resources...

             */

            if (stmt != null) {

                try {

                    stmt.close();

                } catch (sqlexception sqlex) {

                    // ignore -- as we can't do anything about it here

                }

                stmt = null;

            }

            if (conn != null) {

                try {

                    conn.close();

                } catch (sqlexception sqlex) {

                    // ignore -- as we can't do anything about it here

                }

                conn = null;

            }

        }

    }

}

如上例所示,获得JNDI InitialContext并查找到数据库后,其余代码与过去在JDBC编程中使用的类似。

使用连接池时需要牢记的最重要事项是,无论在代码中出现了什么(异常、控制流等),连接以及由连接创建的任何部分(语句、结果集等)均应被关闭,以便能再次使用它们。如不然,它们将纠缠在一起,在最好的情况下,意味着它们所代表的MySQL服务器资源(缓冲区、锁定、套接字等)可能会捆绑一段时间,在最坏的情况下,可能会导致永久捆绑。

连接池的最佳大小是什么?

与所有其他配置经验规则一样,回答是“它取决于具体情况”。尽管最佳大小取决与预期的负载和平均的数据库事务时间,最佳的连接池大小小于你的预期。例如,如果使用的是Sun公司的Java Petstore Blueprint应用程序,对于包含1520个连接的连接池,使用MySQLTomcat,在可接受的相应时间下,可服务于中等程度的负载(600个并发用户)。

要想确定用于应用程序的连接池大小,应使用诸如Apache JmeterThe Grinder等工具创建负载测试脚本,并对应用程序进行负载测试。

确定出发点的一种简单方法是,将连接池的最大连接数配置为“无限”,运行负载测试,并测量最大的并发连接数。随后,应进行反向操作,确定出使应用程序具有最佳性能的连接池的最小和最大值。


什么是命名服务?

命名服务在一个集中位置存储信息,这样用户、计算机和应用程序便可通过网络进行通信。命名服务使用名称查找对象,而不是对象的物理ID。比如说在tomcat中查找JDBC数据源不是通过数据源的直接引用查找,而是通过JNDI与数据源绑定的名称查找(这句话,验证了我之前的猜想:JNDI这种命名服务接口,绑定了使用jdbc配置的数据源,正因为有了java命名和目录服务 即JNDI,所以用户只需要知道这个数据源的名称,就能调用该数据源,完成对数据库的连接操作),比如说通过DNS可以使用域名来访问Web应用,而不是直接通过输入Web服务器的IP地址来访问,这里的数据源的引用和IP地址都可以看作是资源的物理ID。命名服务有DNS,NIS,LDAP等。DNS称为域名系统,开发 DNS 后,网络中的计算机可由通用名称而非 Internet (IP)地址来标识。NIS称为网络信息服务,NIS 的主要作用是通过对各种网络信息进行集中控制来更好地管理网络。NIS 存储有关网络、计算机名称和地址、用户、以及网络服务的信息。

什么是目录服务?

目录服务是命名服务的扩展,目录服务的对象不单有名称,还有属性,既可以通过名称查找对象,也可以通过属性查找到一批对象然后筛选出自己需要的对象。目录服务应该比命名服务更广发,它可以将整个网络中的资源和设备组织起来,形成一个大的目录,然后通过目录就可以定位资源和设备,实现集中管理。

tomcat或Jboss的数据源属于什么服务?

属于命名服务,因为tomcat和Jbosss容器提供了命名服务或者目录服务,然后编程人员想用使用它们的服务时假如没有JNDI则必须遵照它们定的规范来开发,显然两个容器的使用服务的方法是不一样的,所以才有JNDI的规范。也就是说命名和目录服务并不是因为编程而存在的,而是Web容器本身就具有的。

相关文章
|
11月前
|
SQL Java 关系型数据库
JDBC系列-详解各个对象
JDBC系列-详解各个对象
53 0
|
SQL Oracle Java
|
Java 关系型数据库 MySQL
JDBC - 基础篇
JDBC - 基础篇
95 0
JDBC - 基础篇
|
SQL 存储 Java
JDBC中三个重要接口
这里介绍一下JDBC API中最重要的三个接口:Connection、Statement和ResultSet。
|
Java 数据库连接 程序员
程序员,JDBC,JDBC驱动的关系及说明
程序员,JDBC,JDBC驱动的关系及说明
297 0
|
Java 关系型数据库 MySQL
JNDI配置 | 学习笔记
快速学习JNDI配置
144 0
|
SQL Java 关系型数据库
JDBC 结构
JDBC Java 应用通过 JDBC 连接到数据库执行有五步 Register the driver class Creating connection Creating statement Executing queries Closing connection DriverManager class DriverManager 类顾名思义,用来管理 driver。
883 0
|
Java 关系型数据库 程序员
|
Java 数据库连接 容器