Liquibase 配置如下:
liquibase:
enabled: true
change-log: classpath:db/db-changelog.xml
change-log.xml
<includeAll path="changelogs" relativeToChangelogFile="true" />
使用Main方法启动项目,脚本文件的路径:
classpath:db/changelogs/*
将项目使用spring boot打成执行jar,脚本文件的路径变成了
BOOT-INF/classes/db/changelogs/*
因为路径不同的问题,导致脚本会执行多次出错
解决方法:
通过研究Liquibase源码,知道文件路径的解析是通过 XMLChangeLogSAXParser
通过自定义的实现的方式将 BOOT-INF/classes/ 移除,使两种启动方式的路径一致
1. 编写自己的一个 XMLChangeLogSAXParser
public class ChangeLogParser extends XMLChangeLogSAXParser
2. 使Liquibase能扫描到我们的实现
在 META-INF/MANIFEST.MF 中增加
Liquibase-Package: com.xx (ChangeLogParser所在的包)
完整的 ChangeLogParser 代码
public static class ChangeLogParser extends XMLChangeLogSAXParser
{
private final static String BOOT_CLASSES = "BOOT-INF/classes/";
@Override
public int getPriority() {
return 2;
}
@Override
public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParameters changeLogParameters, ResourceAccessor resourceAccessor) throws ChangeLogParseException {
DatabaseChangeLog log = super.parse(physicalChangeLogLocation, changeLogParameters, resourceAccessor);
Iterator<ChangeSet> iterator = log.getChangeSets().iterator();
while( iterator.hasNext() )
{
ChangeSet set = iterator.next();
String filePath = set.getFilePath();
if( filePath.startsWith(BOOT_CLASSES) )
{
set.setFilePath(filePath.substring(BOOT_CLASSES.length()));
}
}
return log;
}
}