此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10! |
控制数据库连接
用DataSource
Spring 通过DataSource
.一个DataSource
是
JDBC 规范的一部分,是一个通用的连接工厂。它允许
容器或框架隐藏连接池和事务管理问题
从应用程序代码。作为开发人员,您无需了解有关如何
连接到数据库。这是设置的管理员的责任
数据源。在开发和测试代码时,您很可能会同时担任这两个角色,但您
不一定知道生产数据源的配置方式。
当您使用 Spring 的 JDBC 层时,您可以从 JNDI 获取数据源,也可以
使用第三方提供的连接池实现配置您自己的连接池实现。
传统的选择是 Apache Commons DBCP 和 C3P0 with bean styleDataSource
类;
对于现代 JDBC 连接池,请考虑使用 HikariCP 及其构建器风格的 API。
您应该使用DriverManagerDataSource 和SimpleDriverDataSource 类
(包含在 Spring 发行版中)仅用于测试目的!这些变体没有
提供池,并且在发出多个连接请求时性能不佳。 |
以下部分使用 Spring 的DriverManagerDataSource
实现。
其他几个DataSource
稍后将介绍变体。
要配置DriverManagerDataSource
:
-
获取与
DriverManagerDataSource
因为您通常会获得 JDBC 连接。 -
指定 JDBC 驱动程序的完全限定类名,以便
DriverManager
可以加载驱动程序类。 -
提供 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
接口应该由可以提供
连接到关系数据库。它扩展了DataSource
让
使用它的类会查询是否应该在给定的
操作。当您知道需要重用连接时,这种用法是有效的。
扩展AbstractDataSource
AbstractDataSource
是一个abstract
Spring 的DataSource
实现。它实现了所有人通用的代码DataSource
实现。
您应该扩展AbstractDataSource
class 如果你自己写的话DataSource
实现。
用SingleConnectionDataSource
这SingleConnectionDataSource
class 是SmartDataSource
将单个Connection
每次使用后不会关闭。
这不支持多线程。
如果任何客户端代码调用close
假设池连接(如使用
持久化工具),您应该将suppressClose
属性设置为true
.此设置
返回包装物理连接的紧密抑制代理。请注意,您可以
不再将其转换为本机 OracleConnection
或类似对象。
SingleConnectionDataSource
主要是一个测试类。它通常可以轻松测试
应用程序服务器外部的代码,结合简单的 JNDI 环境。
与DriverManagerDataSource
,它一直重复使用相同的连接,
避免过度创建物理连接。
用DriverManagerDataSource
这DriverManagerDataSource
class 是标准的实现DataSource
接口,该接口通过 bean 属性配置一个普通的 JDBC 驱动程序,并返回一个新的Connection
每次。
此实现对于 Jakarta EE 之外的测试和独立环境非常有用
容器,可以作为DataSource
Spring IoC 容器中的 bean 或结合使用
使用简单的 JNDI 环境。池假设Connection.close()
调用
关闭连接,因此任何DataSource
-aware 持久性代码应该可以工作。然而
使用 JavaBean 样式的连接池(例如commons-dbcp
)是如此简单,即使在测试中也是如此
环境,几乎总是最好使用这样的连接池而不是DriverManagerDataSource
.
用TransactionAwareDataSourceProxy
TransactionAwareDataSourceProxy
是目标的代理DataSource
.代理将
目标DataSource
以增加对 Spring 管理的事务的认识。在这方面,它
类似于事务性 JNDIDataSource
,由 Jakarta EE 服务器提供。
很少需要使用此类,除非现有代码必须
调用并传递标准 JDBCDataSource 接口实现。在这种情况下,
您仍然可以使用此代码,同时拥有此代码
参与 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
类支持保存点 (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
并可以作为那里的直接替代品。