能否使用单个SpringLiquibase实例执行多个change-log完成迁移?
解决方案
完全可以通过聚合多个change log的方式,只用单个SpringLiquibase实例完成迁移,避免重复创建连接的性能问题,有两种常用实现方式:
方案1:动态构造聚合根ChangeLog
Liquibase本身支持通过根changelog的include标签批量引入其他changelog,你不需要手动创建物理yaml/xml文件,可以直接在代码里构造一个虚拟的根changelog内容,直接喂给SpringLiquibase即可:
void performUpdate(DataSource dataSource, String schema) throws LiquibaseException { // 动态构造根changelog,按顺序引入所有待执行的changelog StringBuilder rootChangeLogContent = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<databaseChangeLog\n" + " xmlns=\"http://www.liquibase.org/xml/ns/dbchangelog\"\n" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xsi:schemaLocation=\"http://www.liquibase.org/xml/ns/dbchangelog\n" + " https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd\">\n"); // 按原有顺序把所有changelog添加到include列表 for (String cl : changeLogList) { rootChangeLogContent.append(" <include file=\"").append(cl).append("\" relativeToChangelogFile=\"false\"/>\n"); } rootChangeLogContent.append("</databaseChangeLog>"); SpringLiquibase liquibase = createLiquibase(); liquibase.setDataSource(dataSource); liquibase.setDefaultSchema(schema); // 直接传入构造好的changelog内容,不需要指向物理文件 liquibase.setChangeLog("inline:" + rootChangeLogContent); liquibase.afterPropertiesSet(); }
这个方案改动最小,完全复用你现有的SpringLiquibase封装逻辑,执行顺序和你原来的for循环顺序完全一致。
方案2:直接使用原生Liquibase API执行多changelog
如果你不想构造XML内容,也可以直接拿到Liquibase原生实例,循环执行每个changelog,全程复用同一个数据库连接:
void performUpdate(DataSource dataSource, String schema) throws LiquibaseException, SQLException { try (Connection conn = dataSource.getConnection()) { // 全局只创建一个Liquibase实例,复用连接 Liquibase liquibase = new Liquibase("", new ClassLoaderResourceAccessor(), new JdbcConnection(conn)); liquibase.setDefaultSchemaName(schema); // 按顺序执行所有changelog for (String cl : changeLogList) { liquibase.update(new Contexts(), new LabelExpression(), cl); } } }
这个方案性能更好,全程只占用一个数据库连接,不需要重复初始化SpringLiquibase的上下文。
注意事项
- 两种方案都严格遵循你原来的changeLogList的顺序执行,不会打乱原有迁移顺序
- DATABASECHANGELOG表中会保留每个changelog对应的记录,和你原来逐个执行的记录完全一致,不会影响后续增量迁移的校验
内容的提问来源于stack exchange,提问作者Joseph Cen
相关产品推荐
相关产品推荐

