该软件包支持初始化 现有的 .嵌入式数据库支持提供了一个用于创建的选项 并为应用程序初始化 A。但是,有时可能需要初始化 在某处服务器上运行的实例。org.springframework.jdbc.datasource.initDataSourceDataSourceSpring中文文档

使用 Spring XML 初始化数据库

如果要初始化数据库,并且可以提供对 Bean 的引用,则可以在命名空间中使用标签:DataSourceinitialize-databasespring-jdbcSpring中文文档

<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.sqlSpring中文文档

数据库初始值设定项的默认行为是无条件运行提供的 脚本。这可能并不总是你想要的——例如,如果你运行 针对已包含测试数据的数据库的脚本。可能性 通过遵循常见模式(如前所示)可以减少意外删除数据的情况 首先创建表,然后插入数据。如果出现以下情况,第一步将失败 这些表已存在。Spring中文文档

但是,为了更好地控制现有数据的创建和删除,XML 命名空间提供了一些附加选项。第一个是用于切换 初始化打开和关闭。您可以根据环境进行设置(例如拉 来自系统属性或环境 Bean 的布尔值)。下面的示例从系统属性中获取一个值:Spring中文文档

<jdbc:initialize-database data-source="dataSource"
	enabled="#{systemProperties.INITIALIZE_DATABASE}"> (1)
	<jdbc:script location="..."/>
</jdbc:initialize-database>
1 从名为 的系统属性中获取 的值。enabledINITIALIZE_DATABASE

控制现有数据发生情况的第二种选择是更加宽容 失败。为此,您可以控制初始值设定项忽略某些 从脚本运行的 SQL 中的错误,如以下示例所示:Spring中文文档

<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
	<jdbc:script location="..."/>
</jdbc:initialize-database>

在前面的示例中,我们说我们期望有时运行脚本 针对空数据库,并且脚本中有一些语句 因此,会失败。所以失败的 SQL 语句会被忽略,但其他失败的 将导致异常。如果您的 SQL 方言不支持(或类似),但您希望在之前无条件删除所有测试数据,这将非常有用 重新创建它。在这种情况下,第一个脚本通常是一组语句, 后跟一组语句。DROPDROPDROP …​ IF EXISTSDROPCREATESpring中文文档

该选项可以设置为(默认值)、(忽略失败) drops),或者(忽略所有失败)。ignore-failuresNONEDROPSALLSpring中文文档

如果字符不是,则每个语句都应用换行符或换行符分隔 完全存在于脚本中。您可以全局控制它,也可以逐个脚本控制它,因为 以下示例显示:;;Spring中文文档

<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-schemaSpring中文文档

如果需要的控制比从 XML 命名空间获得的控制更多,则可以直接使用 并将其定义为应用程序中的组件。DataSourceInitializerSpring中文文档

依赖于数据库的其他组件的初始化

一大类应用程序(那些在 Spring 上下文之后才使用数据库的应用程序 started)可以使用数据库初始值设定项,无需进一步 并发症。如果您的应用程序不是其中之一,则可能需要阅读其余内容 本节的。Spring中文文档

数据库初始值设定项依赖于实例并运行脚本 在其初始化回调中提供(类似于 XML Bean 中的 定义,组件中的方法,或组件中实现的方法)。如果其他 Bean 依赖于 相同的数据源,并在初始化回调中使用数据源,其中 可能是个问题,因为数据尚未初始化。一个常见的例子 这是一个缓存,它急切地初始化并从应用程序上的数据库加载数据 启动。DataSourceinit-method@PostConstructafterPropertiesSet()InitializingBeanSpring中文文档

若要解决此问题,有两个选项: 更改缓存初始化策略 到稍后阶段,或确保首先初始化数据库初始值设定项。Spring中文文档

如果应用程序由您控制,则更改缓存初始化策略可能很容易,否则则不然。 有关如何实现这一点的一些建议包括:Spring中文文档

  • 使缓存在首次使用时延迟初始化,从而改进应用程序启动 时间。Spring中文文档

  • 让缓存或初始化缓存的单独组件实现或 .当应用程序上下文启动时,您可以 通过设置其标志自动启动 A,您可以 通过调用封闭上下文手动启动 A。LifecycleSmartLifecycleSmartLifecycleautoStartupLifecycleConfigurableApplicationContext.start()Spring中文文档

  • 使用 Spring 或类似的自定义观察器机制来触发 缓存初始化。 在以下情况下始终由上下文发布 它随时可以使用(在所有 Bean 都初始化之后),因此这通常很有用 钩子(这是默认的工作方式)。ApplicationEventContextRefreshedEventSmartLifecycleSpring中文文档

确保首先初始化数据库初始值设定项也很容易。关于如何实现这一点的一些建议包括:Spring中文文档

  • 依靠 Spring 的默认行为,即 bean 是 按注册顺序初始化。您可以通过采用通用 在 XML 配置中练习一组元素,这些元素将 应用程序模块,并确保数据库和数据库初始化是 首先列出。BeanFactory<import/>Spring中文文档

  • 分离使用它的业务组件并控制它们的 启动顺序,将它们放在单独的实例中(例如, 父上下文包含 ,子上下文包含业务 组件)。这种结构在 Spring Web 应用程序中很常见,但可以更多 一般适用。DataSourceApplicationContextDataSourceSpring中文文档

1 从名为 的系统属性中获取 的值。enabledINITIALIZE_DATABASE
1 将分隔符脚本设置为 。@@
2 将分隔符设置为 。db-schema.sql;