实战派JSP教程-JNDI与数据库连接池

之前,我们在学JSP时曾提到“JSP四种范围对象的大小依次是pageContext

JNDI的全称是Java Naming and Directory Interface(JAVA命名与目录接口),是一种将对象和名字绑定的技术。使用JNDI,应用程序可以通过资源名字来获得相应的对象、服务或目录。我们以使用JNDI访问Tomcat为例,来详细介绍一下JNDI的使用。

Servers项目中有一个context.xml文件(即Tomcat目录中的context.xml文件),此文件中的信息就可以被所有Web项目共享。

我们在context.xml中,加入以下代码:

其中Context是context.xml文件的根标签。Environment可以用来设置JNDI的元素:name表示当前Environment元素的名字,相当于唯一标示符;value表示name对应的内容值,即name与value构成了一组键值对;type表示value中的内容类型。此Environment的作用就类似于String jndiName =“jndiValue”。之后,在该tomcat中的任意一个Web项目里,均可以获取到此Environment的value值了。

JNDI的演示项目名是StudentManagerWithJNDIPool,该项目是建立在StudentManagerWithPage项目基础之上:

在index.jsp中加入以下代码,用于获取context.xml中的Environment值:

index.jsp

Context和InitialContext都属于javax.naming包。Context对象的lookup()方法可以根据名字查询到context.xml中Environment的value值,并且lookup()中需要使用"java:comp/env/"作为固定前缀。lookup()的返回值为Object,需要强转为需要的类型。

运行结果如图所示。

图运行结果

可以发现,使用JNDI定义的变量(通过context.xml中的Environment元素定义),可以在任意一个Web项目中使用(同一个Tomcat中)。

2连接池与数据源

我们之前一直采用传统的JDBC方式访问数据库。而每次使用JDBC访问数据库时,都需要建立连接和关闭连接,但连接的建立和关闭又是非常耗费系统资源的。为了解决这个问题,我们可以使用数据库连接池技术。

(1)连接池

数据库连接池可以分配、管理及释放数据库连接,它可以使得应用程序重复的使用一个已有的数据库连接,而不再是重新建立一个。而且,如果某一个数据库连接超过了最大空闲时间,数据库连接池也会自动将该连接释放掉,从而明显提高数据库的性能及安全。

数据库连接池的工作原理是,在初始化时连接池会创建一定数量的数据库连接,并将这些连接放在数据库连接池之中。连接的数量不会小于用户设置的最小值;而如果应用程序的连接请求数量大于用户设置的最大值,那么大于最大值的那些请求会被加入在等待队列之中,只有当某些应用程序把正在使用的连接使用完毕并归还给连接池时,在等待队列的请求才会获取到连接。

(2)数据源

数据源(javax.sql.DataSource,简称DataSource)中包含了连接池的具体实现,并且可以管理连接池。应用程序可以从直接数据源中获得数据库连接。

实际开发中,有多种可供使用的数据源:Tomcat内置数据源(Apache dbcp)、DBCP数据源、C3P0数据源、自定义数据源等。

Tomcat内置数据源

Tomcat内置数据源也称为Apache dbcp。我们可以使用JNDI从Tomcat中直接获取该数据源对象。

现在就来讲解如何在项目中使用Apache dbcp:

和JNDI一样,首先需要在Servers项目的context.xml中增加元素。不同的是,配置数据源需要使用Resource元素,而不是Environment,如下,

context.xml

Resource元素的属性介绍如表所示。

表Resource元素属性

与JNDI不同的是:配置数据库连接池,除了要在context.xml中配置以外,还需要在Web应用的web.xml中配置元素:

web.xml

元素中的可以用来对配置的资源进行描述说明,其他的子元素值只需要和context.xml中的相关值保持一致即可,具体如下:

值对应于中的name值;

值对应于中的type值;

值对应于中的auth值。

此外,还需要注意采用数据源方式访问数据库,数据源是由Tomcat创建并维护的,因此还需要把JDBC的驱动包(ojdbc6.jar)复制到Tomcat的lib目录下。

最后,我们修改StudentManagerWithJNDIPool项目的DBUtil.java文件,将传统的JDBC方式替换为数据源方式来访问数据库,如下,

运行此项目,运行结果与之前的完全相同。不同的是,使用连接池的方式来访问数据库,可以提高项目的性能。

我们总结一下,使用Apache dbcp实现数据库连接的步骤:

1配置context.xml文件:在Tomcat的context.xml中加入元素及相关属性

2配置web.xml文件:在项目的web.xml中元素及相关属性

3给Tomcat的lib目录加入相应的数据库驱动

4编码查找数据源(使用lookup()方法),实现连接数据库

DBCP数据源

DBCP(DataBase connection pool,数据库连接池),是Apache组织提供的一个开源连接池。以下是使用DBCP的具体方法:

使用DBCP前,需要先在项目中导入以下JAR包:

其中,commons-dbcp.jar中包含了DBCP的2个核心类:BasicDataSource和BasicDataSourceFactory。我们可以根据这两个类,设计出两种不同的DBCP实现方式:基于BasicDataSource的手动编码方式,以及基于BasicDataSourceFactory的配置文件方式。

a.基于BasicDataSource的手动编码方式

BasicDataSource是DataSource(数据源)接口的实现类,包含了设置数据源对象的具体方法,如表所示。

可以先通过BasicDataSource构造方法产生一个数据源对象,再手动给数据源对象设置属性值,最后返回该数据源对象,如下:

以上,就是使用DBCP数据源获取连接对象(connection)的方法。有了连接对象connection以后,就可以通过createStatement()方法产生Statement对象(或者通过prepareStatement()方法产生PreparedStatement等),进而执行数据库访问

b.基于BasicDataSourceFactory的配置文件方式

BasicDataSourceFactory可以通过createDataSource()方法,从配置文件(Properties文件)中读取数据库配置信息,并获取数据库连接对象。createDataSource()方法的完整定义如下:

以下,是通过BasicDataSourceFactory方式获取DBCP数据源对象的具体代码:

创建并编写配置文件

创建配置文件:

在src上点击鼠标右键àNewàFileà输入dbcpconfig.propertiesàFinish,如图所示。

图新建File

图创建properties文件

编写配置文件:dbcpconfig.properties

获取数据源对象

C3P0数据源

C3P0性能优越并易于扩展,是目前最流行、使用最广的数据源之一。著名的Hibernate、Spring等开源框架,使用的都是该数据源。C3P0实现了DataSource数据源接口,并提供了一个重要的实现类:ComboPooledDataSource,该类的常见方法如表所示。

表ComboPooledDataSource常见方法

可以发现,DBCP和C3P0的实现类都提供了3类方法:(1)设置数据库信息的方法;(2)初始化连接池的方法();(3)获取连接对象的getConnection()方法。

与DBCP类似,在使用C3P0前,需要先导入以下JAR包,如表所示。

表 C3P0所需JAR文件

此外,C3P0也提供了手动编码及配置文件两种方式来获取数据源对象,具体如下:

a.基于无参构造方法ComboPooledDataSource()的手动编码方式

通过手动编码方式获取c3p0对象,依赖于无参构造方法ComboPooledDataSource(),如下:

b.基于有参构造方法ComboPooledDataSource(String configName)的配置文件方式

通过配置文件方式获取c3p0对象,依赖于有参构造方法ComboPooledDataSource(String configName),如下:

创建并编写配置文件

与DBCP不同,c3p0使用的是XML格式的配置文件,并且配置文件必须满足:存放于src根目录下;文件名是c3p0-config.xml。

在src下创建并编写一个c3p0-config.xml文件,如下:

c3p0-config.xml

可以发现,中包含了两套配置数据源信息:和。其中,配置的是默认信息,而是自定义配置。一个中可以包含任意数量的,当包含一个或多个时,用户可以通过有参构造方法ComboPooledDataSource(String configName)中的参数configName来指定实际使用哪一个。此外,如果某些信息在中没有配置,那么c3p0就会自动使用中的相应信息,例如user、password等。

获取数据源对象

有参构造方法ComboPooledDataSource(String configName)会在c3p0-config.xml文件中的所有name="…">里,寻找name=configName的配置信息。

以下代码,通过ComboPooledDataSource("lanqiao"),指定使用c3p0-config.xml中name="lanqiao">的配置信息,再根据配置信息创建数据源对象。

在实际开发中,经常会遇到DBCP或C3P0,因此可以将二者封装到一个工具类中,如下:

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180611A0RTTH00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券