对于最新的稳定版本,请使用 Spring Framework 6.2.0! |
初始化DataSource
该软件包支持初始化
现有的 .嵌入式数据库支持提供了一个用于创建
以及初始化 for for 应用程序。但是,有时可能需要初始化
在某处的服务器上运行的实例。org.springframework.jdbc.datasource.init
DataSource
DataSource
使用 Spring XML 初始化数据库
如果要初始化数据库并且可以提供对 bean 的引用,则可以在名称空间中使用标记:DataSource
initialize-database
spring-jdbc
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="classpath:com/foo/sql/db-schema.sql"/>
<jdbc:script location="classpath:com/foo/sql/db-test-data.sql"/>
</jdbc:initialize-database>
前面的示例对数据库运行两个指定的脚本。第一个
script 创建一个架构,第二个 script 使用测试数据集填充 table。剧本
locations 也可以是带有通配符的模式,采用通常用于资源的 Ant 样式
在 Spring 中(例如 )。如果您使用
pattern,则脚本将按其 URL 或文件名的词法顺序运行。classpath*:/com/foo/**/sql/*-data.sql
数据库初始值设定项的默认行为是无条件地运行提供的 脚本。这可能并不总是您想要的 — 例如,如果您运行 针对已包含测试数据的数据库的脚本。可能性 的意外删除数据通过遵循常见模式来减少(如前所示) 首先创建表,然后插入数据。如果出现以下情况,则第一步失败 表已存在。
但是,为了更好地控制现有数据的创建和删除,XML namespace 提供了一些其他选项。第一个是用于将 initialization on 和 off。你可以根据环境进行设置(比如拉取 boolean 值)。以下示例从 system 属性获取值:
<jdbc:initialize-database data-source="dataSource"
enabled="#{systemProperties.INITIALIZE_DATABASE}"> (1)
<jdbc:script location="..."/>
</jdbc:initialize-database>
1 | 从名为 的系统属性中获取 的值。enabled INITIALIZE_DATABASE |
控制现有数据发生情况的第二个选项是更宽容 失败。为此,您可以控制初始化器忽略某些 错误,如下例所示:
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="..."/>
</jdbc:initialize-database>
在前面的示例中,我们表示我们期望有时运行脚本
针对空数据库,并且脚本中有一些语句
因此,会失败。因此,失败的 SQL 语句将被忽略,但其他失败的语句将被忽略
将导致异常。如果您的 SQL 方言不支持(或类似),但您希望在之前无条件地删除所有测试数据,这将非常有用
重新创建它。在这种情况下,第一个脚本通常是一组语句
后跟一组语句。DROP
DROP
DROP … IF
EXISTS
DROP
CREATE
该选项可以设置为 (默认)、(ignore failed
drops) 或 (ignore all failures) 的 Launch。ignore-failures
NONE
DROPS
ALL
每个语句都应该用 or 换行符分隔(如果字符不是)
完全存在于脚本中。您可以全局控制它,也可以逐个脚本控制它,因为
以下示例显示:;
;
<jdbc:initialize-database data-source="dataSource" separator="@@"> (1)
<jdbc:script location="classpath:com/myapp/sql/db-schema.sql" separator=";"/> (2)
<jdbc:script location="classpath:com/myapp/sql/db-test-data-1.sql"/>
<jdbc:script location="classpath:com/myapp/sql/db-test-data-2.sql"/>
</jdbc:initialize-database>
1 | 将分隔符脚本设置为 .@@ |
2 | 将 的分隔符设置为 。db-schema.sql ; |
在此示例中,这两个脚本使用 as 语句分隔符,并且仅使用
用途 .此配置指定默认分隔符
is 并覆盖脚本的默认值。test-data
@@
db-schema.sql
;
@@
db-schema
如果您需要的控制比从 XML 命名空间获得的控制更多,则可以直接使用 并将其定义为应用程序中的一个组件。DataSourceInitializer
初始化依赖于数据库的其他组件
一大类应用程序(那些在 Spring 上下文具有 started) 可以使用数据库初始化器,而无需再使用 并发症。如果您的应用程序不是其中之一,则可能需要阅读其余部分 本节。
数据库初始值设定项依赖于实例并运行脚本
在其初始化回调中提供(类似于 XML Bean 中的 an
definition、组件中的方法或实现 ) 的组件中的方法 。如果其他 bean 依赖于
相同的数据源并在初始化回调中使用数据源,则
可能是个问题,因为数据尚未初始化。一个常见的例子
这是一个 Cache 缓存,它预先初始化并从 Application 上的数据库加载数据
启动。DataSource
init-method
@PostConstruct
afterPropertiesSet()
InitializingBean
要解决此问题,您有两个选择:更改缓存初始化策略 添加到稍后的阶段,或者确保先初始化数据库初始值设定项。
如果应用程序由您控制,则更改缓存初始化策略可能很容易。 有关如何实现此功能的一些建议包括:
-
使缓存在首次使用时延迟初始化,从而改善应用程序启动 时间。
-
让您的缓存或初始化缓存的单独组件实现 或 .当应用程序上下文启动时,您可以 通过设置它的标志来自动启动 A,你可以 通过调用 Enclosing 上下文手动启动 A。
Lifecycle
SmartLifecycle
SmartLifecycle
autoStartup
Lifecycle
ConfigurableApplicationContext.start()
-
使用 Spring 或类似的自定义观察者机制来触发 cache 初始化。 始终由 context 发布,当 它已准备好使用(在所有 bean 都已初始化之后),因此这通常是有用的 hook (这是默认的工作方式)。
ApplicationEvent
ContextRefreshedEvent
SmartLifecycle
确保首先初始化数据库初始值设定项也很容易。有关如何实现此功能的一些建议包括:
-
依赖于 Spring 的默认行为,即 bean 是 按注册顺序初始化。您可以通过采用通用的 在 XML 配置中对一组元素进行排序的实践 应用程序模块,并确保数据库和数据库初始化 列在第一位。
BeanFactory
<import/>
-
分离 和 使用它的业务组件并控制它们的 启动顺序,将它们放在单独的实例中(例如, 父上下文包含 ,子上下文包含业务 组件)。这种结构在 Spring Web 应用程序中很常见,但可能更多 普遍适用。
DataSource
ApplicationContext
DataSource