Я использую liquibase (3.1.1) в среде Spring (3.2.x) и загружаю наборы изменений через тег inlcudeAll в мастер-файле. Там я использую "classpath*:/package/to/changesets" в качестве пути.
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<includeAll path="classpath*:/package/to/changesets"/>...
Я использую стратегию именования, например «nnn_changesetname.xml», чтобы сохранить порядок. Но когда я просматриваю таблицу наборов изменений, этот порядок по именам файлов не сохраняется. Это работает только в том случае, если файлы набора изменений содержатся в каталоге, а не в пути к классам?
Обновить
Привет, я обнаружил, что предложенного ниже решения недостаточно. Я думаю, что это связано с реализацией того, как liquibase разрешает атрибут includeAll. В моем случае он сначала разрешает все «папки», а затем просматривает каждую папку в поисках XML-файлов набора изменений. Это нарушит порядок файлов xml во всех местоположениях classpath*:/changes, потому что теперь есть несколько папок «changes» в разных местах. В таком случае я бы заподозрил слияние всего содержимого этих «виртуальных» папок пути к классам и загрузку всех ресурсов в одном перечислении. Или мы могли бы позволить некоторому шаблону ресурсов в теге inlcudeAll, например resources="classpath*:/changes/*.xml", напрямую выбирать все необходимые файлы (попробовали с атрибутом path, но не сработало, потому что он проверяет наличие папка)?
Обновить
Я сделал хак, чтобы проверить, сохраняется ли порядок в возвращаемом перечислении с ответом снизу. Для этого я проверил данное имя пакета, и если оно соответствует моему шаблону, я добавил к нему дополнительный «*.xml». С этим расширением я получаю все изменения по мере необходимости.
@Override
public Enumeration<URL> getResources(String packageName)
throws IOException {
if(packageName.equals("classpath*:/plugin/liquibase/changes/")) {
packageName = packageName + "*.xml";
}
List<URL> resources = Collections.list(super.getResources(packageName));
Collections.sort(resources, new Comparator<URL>() {
@Override
public int compare(URL url1, URL url2) {
String path1 = FilenameUtils.getName(url1.getPath());
String path2 = FilenameUtils.getName(url2.getPath());
return String.CASE_INSENSITIVE_ORDER.compare(path1, path2);
}
});
logger.info("Found resources: {}", resources);
return Collections.enumeration(resources);
}};
В журнале теперь я вижу, что ресурсы имеют правильный порядок. Но когда я смотрю в таблицу DATABASECHANGELOCK, она не отражает порядок, который у меня был в перечислении. Так что кажется, что эти значения переопределяются где-то еще.
Обновить
Далее проанализировал код и обнаружил, что класс liquibase.parser.core.xml.XMLChangeLogSAXHandler производит переупорядочивание возвращаемого перечисления. Так что мои изменения не будут иметь никакого эффекта. Я не думаю, что смогу взломать и этот класс.