4.9.?连接池和数据源

4.9.1. 概述
4.9.2. 应用服务器:ConnectionPoolDataSource
4.9.3. 应用:DataSource
4.9.4. 数据源和JNDI

4.9.1.?概述

JDBC API为连接池提供了一个客户端和一个服务器端的接口。客户端接口是javax.sql.DataSource,通常就是应用代码用来请求一个缓冲了的数据库连接的东西。服务器接口是 javax.sql.ConnectionPoolDataSource,通常是大多数应用服务器和UXDB JDBC驱动之间使用的接口。

在应用服务器环境里,应用服务器配置通常将指向UXDB ConnectionPoolDataSource实现, 而应用组件代码将通常要求一个由应用服务器实现的DataSource(不是UXDB)。

在一个没有应用服务器的环境里,UXDB提供了两种应用可以直接使用的DataSource的实现。 一种实现执行连接池,另外一种只是简单的通过DataSource接口提供访问数据库的连接, 而不使用任何缓冲池。同样,这些实现不应该在一个应用服务器环境里使用,除非应用服务器不支持ConnectionPoolDataSource接口。

4.9.2.?应用服务器:ConnectionPoolDataSource

UXDB包含了一个用于JDBC 2的ConnectionPoolDataSource的实现,以及一个用于JDBC 3的实现。

表?4.6.?ConnectionPoolDataSource实现

JDBC实现类
2org.UXDB.jdbc2.optional.ConnectionPool
3org.UXDB.jdbc3.Jdbc3ConnectionPool

两种实现都使用了同样的配置模式。JDBC要求一个ConnectionPoolDataSource通过JavaBean属性来实现,因此每个这样的属性都存在获取和设置方法:

表?4.7.?ConnectionPoolDataSource 配置属性

属性类型描述
serverNameStringUXDB 数据库服务器主机名
databaseNameStringUXDB 数据库名
portNumberintUXDB 数据库服务器监听的 TCP/IP 端口 (为 0 则使用缺省端口)
userString用来进行数据库连接的用户
passwordString用来进行数据库连接的口令
defaultAutoCommitboolean提交给调用者的时候连接是应该打开autoCommit还是应该关闭。 缺省是false,关闭autoCommit

许多应用服务器使用属性风格的语法来配置这些属性, 因此把属性当作一块文本输入应该并不罕见。 如果应用服务器提供了单块的区域输入所有属性,如下所示:

serverName=localhost
databaseName=test
user=testuser
password=testpassword

或者使用分号而不是换行做分隔符,如下所示:

serverName=localhost;databaseName=test;user=testuser;password=testpassword

4.9.3.?应用:DataSource

UXDB包含两个用于JDBC 2的DataSource,还有两个用于JDBC 3的,如DataSource 实现所示。连接池的实现在客户端调用 close 方法的时候实际上并不关闭连接, 而是把连接返回到一个可用连接的连接池中给其它客户端使用。 这样就避免了任何重复打开和关闭连接造成的开销,并且允许大量的客户端分享相对较少的数据库连接。

这里提供的连接池数据源实现并非世上特性最丰富的。 比如,连接在池本身关闭之前绝对不会关闭;而且也没有办法缩小连接池。 同样,非缺省配置的用户的连接请求无法如池。许多应用服务器提供更加高级的连接池特性,并且使用的是ConnectionPoolDataSource实现。

表?4.8.?DataSource 实现

JDBC连接池实现类
2org.UXDB.jdbc2.optional.SimpleDataSource
2org.UXDB.jdbc2.optional.PoolingDataSource
3org.UXDB.jdbc3.Jdbc3SimpleDataSource
3org.UXDB.jdbc3.Jdbc3PoolingDataSource

所有实现使用同样的配置模式。JDBC要求DataSource 通过JavaBean属性配置,在DataSource 配置属性里列出。 因此每种这个属性都有获取和设置属性的方法。

表?4.9.?DataSource 配置属性

属性类型描述
serverNameStringUXDB数据库服务器主机名
databaseNameStringUXDB数据库名
portNumberintUXDB数据库服务器监听的TCP端口(或者0表示使用缺省端口)
userString用来进行数据库连接的用户
passwordString用来进行数据库连接的口令

连接池实现要求一些额外的配置属性,如下所示:

表?4.10.?额外的连接池DataSource配置属性

属性类型描述
dataSourceNameString每一个连接池DataSource必须有一个唯一的名字
initialConnectionsint连接池初始化的时候要创建的数据库连接数目
maxConnectionsint允许打开的最大数据库连接个数。如果请求了更多的连接, 那么调用者将挂起,直到有一个连接返回给连接池

示例

显示了一个使用连接池DataSource的典型应用的代码。

初始化连接池DataSource,如下所示:

Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource();
source.setDataSourceName("A Data Source");
source.setServerName("localhost");
source.setDatabaseName("test");
source.setUser("testuser");
source.setPassword("testpassword");
source.setMaxConnections(10);

然后使用来自连接池的代码,如下所示。 请注意最终要关闭连接是非常关键的,否则这个池子就会"泄漏"连接, 最后把所有客户端都锁在外面。

Connection con = null;
try {
    con = source.getConnection();
    // 使用连接
} catch (SQLException e) {
    // 记录错误
} finally {
    if (con != null) {
        try { con.close(); } catch (SQLException e) {}
    }
};

4.9.4.?数据源和JNDI

所有ConnectionPoolDataSource和DataSource实现都可以存储在JNDI里。在非连接池的实现中, 每次从JNDI中检索对象都将创建一个新的实例, 带有和存储的实例同样的设置。对于连接池实现而言,同一个实例是在可得的情况下检索出来的(也就是说,没有其它JVM从JNDI中检索连接池),否则就创建同样设置的新的实例。

在应用服务器环境,通常是应用服务器的DataSource实例将存储在JNDI中,而不是UXDB ConnectionPoolDataSource的实现。 在应用服务器环境,应用可以在JNDI中存储DataSource, 这样它就不用制作一个指向DataSource的引用提供给 所有可能需要的应用组件使用它。

示例

初始化连接池DataSource并且把它加到JND,如下所示:

Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource();
source.setDataSourceName("A Data Source");
source.setServerName("localhost");
source.setDatabaseName("test");
source.setUser("testuser");
source.setPassword("testpassword");
source.setMaxConnections(10);
new InitialContext().rebind("DataSource", source);

之后使用来自连接池的代码,如下所示:

Connection con = null;
try {
    DataSource source = (DataSource)new InitialContext().lookup("DataSource");
    con = source.getConnection();
    // 使用连接
} catch (SQLException e) {
    // 记录错误
} catch (NamingException e) {
    // 在 JNDI 里没有找到 DataSource
} finally {
    if (con != null) {
        try { con.close(); } catch (SQLException e) {}
    }
}
XML 地图 | Sitemap 地图