使用 Liquibase 通过 ORM 填充数据
Using Liquibase to populate data with ORM
我目前正在使用 Liquibase 创建数据库模式。这是一个使用休眠 ORM 的 spring 启动应用程序。
Liquibase 在应用程序启动之初、ORM 初始化之前更改数据库架构(以便 ORM 在初始化时查看正确的架构)。
但是在应用程序启动后我想 运行 Liquibase 第二次在 ORM 和 java 代码的帮助下填充数据库中的数据(使用 java变更集:Java code changeset in liquibase ).
使用 Liquibase 用 ORM 和 java 填充数据的原因是因为 Liquibase 在集群中正常工作(例如,如果我们同时启动了 3 个节点,则只有一个节点会填充数据).
是否有可能 运行 Liquibase 在“2 个阶段”?
第一次,在应用程序启动期间更新数据库架构,第二次,在应用程序启动后,使用 ORM 填充一些数据。我们需要从 java 代码中做到这一点。
以前在使用 Flyway 时,我们通过拥有 2 个 Flyway 实例来做到这一点,每个实例都有单独的更改,并且 运行在应用程序启动开始之前在 ORM 初始化之前设置第一个实例,在 ORM 之后设置第二个实例启动完成,初始化ORM。
以下解决方案似乎有效:
@Component
class LiquibaseOrmMigrationRunner(val dataSource: DataSource, val resourceLoader: ResourceLoader, val environment: Environment) :
ApplicationListener<ContextRefreshedEvent> {
override fun onApplicationEvent(event: ContextRefreshedEvent) {
val isLiquibaseEnabled = environment.getProperty("spring.liquibase.enabled", Boolean::class.java, true)
if (!isLiquibaseEnabled) {
return
}
var liquibase: Liquibase? = null
try {
val changeLogFile = "classpath:/db/changelog/orm/db.changelog-master-orm.yaml"
val connection = dataSource.connection
val liquibaseConnection = JdbcConnection(connection)
val database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(liquibaseConnection)
database.databaseChangeLogTableName = "ORMDATABASECHANGELOG"
database.databaseChangeLogLockTableName = "ORMDATABASECHANGELOGLOCK"
val resourceAccessor = SpringResourceAccessor(resourceLoader)
liquibase = Liquibase(changeLogFile, resourceAccessor, database)
liquibase.update(Contexts(), LabelExpression())
} catch (e: SQLException) {
throw DatabaseException(e)
} finally {
if (liquibase != null) {
liquibase.close()
}
}
}
}
这会创建一个额外的 liquibase 实例,该实例在 spring 启动配置的默认实例之后运行。
要使用 orm 填充数据库,附加的 liquibase 实例会执行以下变更集
databaseChangeLog:
- changeSet:
id: initial_data
author: author
changes:
- customChange: { "class": "com.example.LiquibaseInitialDataMigrationOrm" }
自定义更改如下所示:
class LiquibaseInitialDataMigrationOrm : CustomTaskChange {
override fun execute(database: Database?) {
val initialDataService = SpringApplicationContextSingleton.getBean("initialDataService") as InitialDataService
initialDataService.populateInitialData()
}
override fun getConfirmationMessage(): String {
return "Initial Data Liquibase ORM Migration finished"
}
@Suppress("EmptyFunctionBlock")
override fun setUp() {
}
@Suppress("EmptyFunctionBlock")
override fun setFileOpener(resourceAccessor: ResourceAccessor?) {
}
override fun validate(database: Database?): ValidationErrors {
return ValidationErrors()
}
}
自定义更改使用包含 spring 应用程序上下文的单例
我目前正在使用 Liquibase 创建数据库模式。这是一个使用休眠 ORM 的 spring 启动应用程序。
Liquibase 在应用程序启动之初、ORM 初始化之前更改数据库架构(以便 ORM 在初始化时查看正确的架构)。
但是在应用程序启动后我想 运行 Liquibase 第二次在 ORM 和 java 代码的帮助下填充数据库中的数据(使用 java变更集:Java code changeset in liquibase ).
使用 Liquibase 用 ORM 和 java 填充数据的原因是因为 Liquibase 在集群中正常工作(例如,如果我们同时启动了 3 个节点,则只有一个节点会填充数据).
是否有可能 运行 Liquibase 在“2 个阶段”?
第一次,在应用程序启动期间更新数据库架构,第二次,在应用程序启动后,使用 ORM 填充一些数据。我们需要从 java 代码中做到这一点。
以前在使用 Flyway 时,我们通过拥有 2 个 Flyway 实例来做到这一点,每个实例都有单独的更改,并且 运行在应用程序启动开始之前在 ORM 初始化之前设置第一个实例,在 ORM 之后设置第二个实例启动完成,初始化ORM。
以下解决方案似乎有效:
@Component
class LiquibaseOrmMigrationRunner(val dataSource: DataSource, val resourceLoader: ResourceLoader, val environment: Environment) :
ApplicationListener<ContextRefreshedEvent> {
override fun onApplicationEvent(event: ContextRefreshedEvent) {
val isLiquibaseEnabled = environment.getProperty("spring.liquibase.enabled", Boolean::class.java, true)
if (!isLiquibaseEnabled) {
return
}
var liquibase: Liquibase? = null
try {
val changeLogFile = "classpath:/db/changelog/orm/db.changelog-master-orm.yaml"
val connection = dataSource.connection
val liquibaseConnection = JdbcConnection(connection)
val database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(liquibaseConnection)
database.databaseChangeLogTableName = "ORMDATABASECHANGELOG"
database.databaseChangeLogLockTableName = "ORMDATABASECHANGELOGLOCK"
val resourceAccessor = SpringResourceAccessor(resourceLoader)
liquibase = Liquibase(changeLogFile, resourceAccessor, database)
liquibase.update(Contexts(), LabelExpression())
} catch (e: SQLException) {
throw DatabaseException(e)
} finally {
if (liquibase != null) {
liquibase.close()
}
}
}
}
这会创建一个额外的 liquibase 实例,该实例在 spring 启动配置的默认实例之后运行。
要使用 orm 填充数据库,附加的 liquibase 实例会执行以下变更集
databaseChangeLog:
- changeSet:
id: initial_data
author: author
changes:
- customChange: { "class": "com.example.LiquibaseInitialDataMigrationOrm" }
自定义更改如下所示:
class LiquibaseInitialDataMigrationOrm : CustomTaskChange {
override fun execute(database: Database?) {
val initialDataService = SpringApplicationContextSingleton.getBean("initialDataService") as InitialDataService
initialDataService.populateInitialData()
}
override fun getConfirmationMessage(): String {
return "Initial Data Liquibase ORM Migration finished"
}
@Suppress("EmptyFunctionBlock")
override fun setUp() {
}
@Suppress("EmptyFunctionBlock")
override fun setFileOpener(resourceAccessor: ResourceAccessor?) {
}
override fun validate(database: Database?): ValidationErrors {
return ValidationErrors()
}
}
自定义更改使用包含 spring 应用程序上下文的单例