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