|
对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
控制数据库连接
用DataSource
Spring 通过DataSource. 一个DataSource是 JDBC 规范的一部分,是一个通用的连接工厂。它允许容器或框架隐藏连接池和事务管理问题从应用程序代码中。作为开发人员,您不需要了解有关如何连接到数据库的详细信息。这是设置数据源的管理员的责任。在开发和测试代码时,您很可能会同时担任这两个角色,但您不一定必须知道生产数据源是如何配置的。
当您使用 Spring 的 JDBC 层时,您可以从 JNDI 获取数据源,也可以使用第三方提供的连接池实现配置您自己的。传统的选择是 Apache Commons DBCP 和 C3P0 与 bean 样式DataSource类; 对于现代 JDBC 连接池,请考虑使用 HikariCP 及其构建器风格的 API。
您应该使用DriverManagerDataSource和SimpleDriverDataSource类 (包含在 Spring 发行版中)仅用于测试目的!这些变体不会提供池化,并且在发出多个连接请求时性能不佳。 |
以下部分使用 Spring 的DriverManagerDataSource实现。 其他几个DataSource稍后将介绍变体。
要配置DriverManagerDataSource:
-
获取与
DriverManagerDataSource因为您通常会获得 JDBC 连接。 -
指定 JDBC 驱动程序的完全限定类名,以便
DriverManager可以加载驱动程序类。 -
提供 JDBC 驱动程序之间的 URL。(请参阅驱动程序的文档以获取正确的值。
-
提供用户名和密码以连接到数据库。
以下示例演示如何配置DriverManagerDataSource在 Java 中:
-
Java
-
Kotlin
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
dataSource.setUrl("jdbc:hsqldb:hsql://localhost:");
dataSource.setUsername("sa");
dataSource.setPassword("");
val dataSource = DriverManagerDataSource().apply {
setDriverClassName("org.hsqldb.jdbcDriver")
url = "jdbc:hsqldb:hsql://localhost:"
username = "sa"
password = ""
}
以下示例显示了相应的 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"/>
用DataSourceUtils
这DataSourceUtilsclass 是一个方便而强大的辅助类,它提供了static从 JNDI 获取连接并在必要时关闭连接的方法。
它支持线程绑定的 JDBCConnection跟DataSourceTransactionManager但
还与JtaTransactionManager和JpaTransactionManager.
请注意JdbcTemplate意味 着DataSourceUtils连接访问, 使用它
在每个 JDBC作背后,隐式参与正在进行的事务。
实施SmartDataSource
这SmartDataSource接口应该由可以提供
连接到关系数据库。它扩展了DataSource让
使用它的类会查询是否应该在给定的
操作。当您知道需要重用连接时,这种用法是有效的。
扩展AbstractDataSource
AbstractDataSource是一个abstractSpring 的DataSource实现。它实现了所有人通用的代码DataSource实现。
您应该扩展AbstractDataSourceclass 如果你自己写的话DataSource实现。
用SingleConnectionDataSource
这SingleConnectionDataSourceclass 是SmartDataSource将单个Connection每次使用后不会关闭。
这不支持多线程。
如果任何客户端代码调用close假设池连接(如使用
持久化工具),您应该将suppressClose属性设置为true.此设置
返回包装物理连接的紧密抑制代理。请注意,您可以
不再将其转换为本机 OracleConnection或类似对象。
SingleConnectionDataSource主要是一个测试类。它通常可以轻松测试
应用程序服务器外部的代码,结合简单的 JNDI 环境。
与DriverManagerDataSource,它一直重复使用相同的连接,
避免过度创建物理连接。
用DriverManagerDataSource
这DriverManagerDataSourceclass 是标准的实现DataSource接口,该接口通过 bean 属性配置一个普通的 JDBC 驱动程序,并返回一个新的Connection每次。
此实现对于 Jakarta EE 之外的测试和独立环境非常有用
容器,可以作为DataSourceSpring IoC 容器中的 bean 或结合使用
使用简单的 JNDI 环境。池假设Connection.close()调用
关闭连接,因此任何DataSource-aware 持久性代码应该可以工作。然而
使用 JavaBean 样式的连接池(例如commons-dbcp)是如此简单,即使在测试中也是如此
环境,几乎总是最好使用这样的连接池而不是DriverManagerDataSource.
用TransactionAwareDataSourceProxy
TransactionAwareDataSourceProxy是目标的代理DataSource.代理将
目标DataSource以增加对 Spring 管理的事务的认识。在这方面,它
类似于事务性 JNDIDataSource,由 Jakarta EE 服务器提供。
很少需要使用此类,除非现有代码必须
调用并传递标准 JDBCDataSource接口实现。在这种情况下,
您仍然可以使用此代码,同时拥有此代码
参与 Spring 管理的事务。通常最好将您的
使用更高级别的抽象进行资源管理来拥有新代码,例如JdbcTemplate或DataSourceUtils. |
请参阅TransactionAwareDataSourceProxyjavadoc 了解更多详情。
用DataSourceTransactionManager / JdbcTransactionManager
这DataSourceTransactionManagerclass 是一个PlatformTransactionManager单个 JDBC 的实现DataSource.它绑定一个 JDBCConnection从指定的DataSource到当前正在执行的线程,可能
允许一个线程绑定Connection每DataSource.
需要应用程序代码才能检索 JDBCConnection通过DataSourceUtils.getConnection(DataSource)而不是 Java EE 的标准DataSource.getConnection.它不受检查地抛出org.springframework.dao异常
而不是选中SQLExceptions.所有框架类(例如JdbcTemplate)使用
这种策略隐含。如果不与事务管理器一起使用,则查找策略
行为与DataSource.getConnection因此可以在任何情况下使用。
这DataSourceTransactionManager类支持保存点 (PROPAGATION_NESTED),
自定义隔离级别,以及作为适当 JDBC 语句应用的超时
查询超时。要支持后者,应用程序代码必须使用JdbcTemplate或
调用DataSourceUtils.applyTransactionTimeout(..)方法。
您可以使用DataSourceTransactionManager而不是JtaTransactionManager在
单资源情况,因为它不需要容器支持 JTA 事务
协调者。在这些事务管理器之间切换只是配置问题,
前提是您坚持所需的连接查找模式。请注意,JTA 不支持
保存点或自定义隔离级别,并且具有不同的超时机制,但除此之外
在 JDBC 资源和 JDBC 提交/回滚管理方面公开了类似的行为。
对于 JTA 风格的实际资源连接的延迟检索,Spring 提供了一个
相应DataSource目标连接池的代理类:请参阅LazyConnectionDataSourceProxy.
这对于没有实际语句的潜在空事务特别有用
执行(在这种情况下从不获取实际资源),并且在
路由DataSource这意味着采用事务同步只读标志
和/或隔离级别(例如IsolationLevelDataSourceRouter).
LazyConnectionDataSourceProxy还为只读连接提供特殊支持
池,避免切换 JDBC 的开销
获取时每个事务开始和结束时的 Connection 的只读标志
它来自主连接池(这可能会很昂贵,具体取决于 JDBC 驱动程序)。
从 5.3 开始,Spring 提供了一个扩展的JdbcTransactionManager变体,它添加了
提交/回滚时的异常转换功能(与JdbcTemplate).
哪里DataSourceTransactionManager只会扔TransactionSystemException(类似于 JTA),JdbcTransactionManager将数据库锁定失败等转换为
相应DataAccessException子。请注意,应用程序代码需要
为此类例外情况做好准备,而不仅仅是期望TransactionSystemException.
在这种情况下,JdbcTransactionManager是推荐的选择。 |
在异常行为方面,JdbcTransactionManager大致相当于JpaTransactionManager也对R2dbcTransactionManager,作为立即
相互陪伴/替代。DataSourceTransactionManager另一方面
相当于JtaTransactionManager并可以作为那里的直接替代品。