3.4控制数据库连接

本节内容包括:

  • 使用DataSource

  • 使用DataSourceUtils

  • 实现SmartDataSource

  • 扩展AbstractDataSource

  • 使用SingleConnectionDataSource

  • 使用DriverManagerDataSource

  • 使用TransactionAwareDataSourceProxy

  • 使用DataSourceTransactionManager

3.4.1 使用数据源

Spring通过数据源获得与数据库的连接。数据源是JDBC规范的一部分,是通用的连接工厂。它允许容器或框架从应用程序代码中隐藏连接池和事务管理问题。作为开发人员,你无需了解有关如何连接到数据库的详细信息。这是设置数据源的管理员的责任。你很可能在开发和测试代码时同时担当这两个角色,但是不必一定要知道如何配置生产数据源。

使用Spring的JDBC层时,你可以从JNDI获取数据源,也可以使用第三方提供的连接池实现来配置自己的数据源。流行的实现是Apache Jakarta Commons DBCP和C3P0。 Spring发行版中的实现仅用于测试目的,不提供池化。

本部分使用Spring的DriverManagerDataSource实现,稍后将介绍其他一些实现。

你应仅将DriverManagerDataSource类用于测试目的,因为它不提供缓冲池,并且在发出多个连接请求时性能不佳。

要配置DriverManagerDataSource:

  1. 通常会获得JDBC连接,因此获得与DriverManagerDataSource的连接。

  2. 指定JDBC驱动程序的标准类名,以便DriverManager可以加载驱动程序类。

  3. 提供在JDBC驱动程序之间变化的URL。 (有关正确的值,请参阅驱动程序的文档。)

  4. 提供用户名和密码以连接到数据库。

以下示例显示了如何在Java中配置DriverManagerDataSource:

DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
dataSource.setUsername("sa");
dataSource.setPassword("");

下面是相应的XML配置:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<context:property-placeholder location="jdbc.properties"/>

接下来的两个示例显示了DBCP和C3P0的基本连接和配置。 要了解更多有助于控制池功能的选项,请参阅相应连接池实现的产品文档。

以下示例显示了DBCP配置:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<context:property-placeholder location="jdbc.properties"/>

下面是C3P0的例子:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driverClassName}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

<context:property-placeholder location="jdbc.properties"/>

3.4.2 使用DataSourceUtils

DataSourceUtils类是一种方便且功能强大的帮助器类,它提供静态方法从JNDI获取连接并在必要时关闭连接。它支持使用例如DataSourceTransactionManager进行线程绑定的连接。

3.4.3 实施SmartDataSource

SmartDataSource接口应该由可以提供与关系数据库的连接的类来实现。它扩展了DataSource接口,以允许使用它的类查询在给定操作后是否应关闭连接。当你知道需要重用连接时,这种用法很有效。

3.4.4 扩展AbstractDataSource

AbstractDataSource是Spring的DataSource实现的抽象基类。它实现了所有DataSource实现通用的代码。如果编写自己的DataSource实现,则应该扩展AbstractDataSource类。

3.4.5 使用SingleConnectionDataSource

SingleConnectionDataSource类是SmartDataSource接口的实现,该接口包装了每次使用后都未关闭的单个Connection。这不是多线程功能。

如果假设共享池连接(例如使用持久性工具)时有任何客户端代码调用关闭,则应将preventClose属性设置为true。此设置将返回用于封装物理连接的封闭代理。请注意,你不能再将此对象转换为本地Oracle Connection或类似对象。

SingleConnectionDataSource主要是一个测试类。例如,它结合简单的JNDI环境,可以在应用服务器外部轻松测试代码。与DriverManagerDataSource相比,它始终重用同一连接,避免了过多的物理连接创建。

3.4.6 使用DriverManagerDataSource

DriverManagerDataSource类是标准DataSource接口的实现,该接口通过bean属性配置纯JDBC驱动程序,并每次返回一个新的Connection。

此实现对于Java EE容器外部的测试和独立环境非常有用,可以作为Spring IoC容器中的DataSource bean或与简单的JNDI环境结合使用。假定使用池的Connection.close()调用将关闭连接,因此任何可识别DataSource的持久性代码都应起作用。但是,即使在测试环境中,使用JavaBean风格的连接池(例如commons-dbcp)也是如此容易,以至总是总是最好在DriverManagerDataSource上使用这样的连接池。

3.4.7 使用TransactionAwareDataSourceProxy

TransactionAwareDataSourceProxy是目标数据源的代理。代理包装该目标数据源以增加对Spring管理的事务的认识。在这方面,它类似于Java EE服务器提供的事务性JNDI数据源。

除非需要调用已经存在的代码并通过标准的JDBC DataSource接口实现,否则很少需要使用此类。 在这种情况下,你仍然可以使该代码可用,同时使该代码参与Spring托管的事务。 通常,最好使用更高级别的资源管理抽象来编写自己的新代码,例如JdbcTemplate或DataSourceUtils。

3.4.8 使用DataSourceTransactionManager

DataSourceTransactionManager类是单个JDBC数据源的PlatformTransactionManager实现。它将JDBC连接从指定的数据源绑定到当前正在执行的线程,可能允许每个数据源一个线程连接。

通过DataSourceUtils.getConnection(DataSource)而不是Java EE的标准DataSource.getConnection检索JDBC连接需要应用程序代码。它抛出未经检查的org.springframework.dao异常,而不是经过检查的SQLException。所有框架类(例如JdbcTemplate)都隐式使用此策略。如果不与该事务管理器一起使用,则查找策略的行为与普通策略完全相同。因此,可以在任何情况下使用它。

DataSourceTransactionManager类支持自定义隔离级别和超时,这些隔离级别和超时将作为适当的JDBC语句查询超时应用。为了支持后者,应用程序代码必须使用JdbcTemplate或为每个创建的语句调用DataSourceUtils.applyTransactionTimeout(..)方法。

在单资源情况下,可以使用此实现而不是JtaTransactionManager,因为它不需要容器支持JTA。只要你坚持要求的连接查找模式,就可以在两者之间进行切换只是配置问题。 JTA不支持自定义隔离级别。

最后更新于