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