Как использовать liquibase для генерации журнала изменений из различий между базой данных и персистентными сущностями весной?
Пожалуйста, мне нужно решение вышеуказанного вопроса весной (на основе конфигурации JAVA), а НЕ в весенней загрузке. Большинство учебных пособий, которые я нашел в Интернете, основаны на весенней загрузке, но мое приложение не работает на весенней загрузке, просто весенний mvc. У меня есть необходимые зависимости, уже находящиеся в моем classpath, это банки liquibase-core-3.5.3 и liquibase-hibernate5-3.6.
Я также создал файл свойств liquibase (тоже в classpath), как показано ниже
driver=com.mysql.jdbc.Driver
changeLogFile=classpath:db-changelog.xml
url=jdbc:mysql://localhost:3306/mydatabase
username=myusername
password=mypassword
referenceUrl=hibernate:spring:com.mypackage.entity?dialect=org.hibernate.dialect.MySQL5InnoDBDialect
diffChangeLogFile=com/mypackage/dbchangelog/diff-changelog.xml
Теперь проблема в том, как мне выполнить его, чтобы сгенерировать файл diff changelog?
2 ответа
Вы должны будете сделать это, используя плагин liquibase для maven или gradle, в зависимости от того, что вы используете для сборки.
Плагин Maven также очень хорошая документация о том, как вы можете запускать команды liquibase.
Если вы используете Gradle, плагин liquibase не работает гладко при вызове diffChangeLog
,
На основе этого ответа создайте файл с именем liquibase.gradle
, Я отредактировал некоторые свойства согласно hibernate5
так как он не поддерживает ImprovedNamingStrategy
больше.
def diffLog = "$projectDir/src/main/resources/db/changelog/db.changelog.yaml"
configurations {
liquibase
}
dependencies {
liquibase 'org.liquibase.ext:liquibase-hibernate5:3.6'
}
task liquibaseDiffChangelog(type: JavaExec) {
group = "liquibase"
classpath sourceSets.main.runtimeClasspath
classpath configurations.liquibase
main = "liquibase.integration.commandline.Main"
args "--changeLogFile=" + diffLog
args "--referenceUrl=hibernate:spring:com.mypackage.entity?hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&dialect=org.hibernate.dialect.MySQL5Dialect"
args "--username=<username>"
args "--password=<password>"
args "--url=jdbc:mysql://<db_host_and_port>/<db_name>"
args "--referenceDriver=liquibase.ext.hibernate.database.connection.HibernateDriver"
args "diffChangeLog"
}
добавлять apply from: 'liquibase.gradle'
в вашем build.gradle
,
Теперь, чтобы сгенерировать diffChangeLog, вызовите gradle liquibaseDiffChangelog
,
Обратите внимание, что в примере используется один из классов весенней загрузки в качестве стратегии именования Hibernate. Вы можете создать свою собственную реализацию, обратившись к этому ответу.
Вот конфигурация бобов весны:
@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog("classpath:db-changelog.xml");
liquibase.setDataSource(dataSource());
return liquibase;
}
и xml config от [liquibase - веб-сайт][1]
<bean id="liquibase" class="liquibase.integration.spring.SpringLiquibase">
<property name="dataSource" ref="myDataSource" />
<property name="changeLog" value="classpath:db-changelog.xml" />
<!--
contexts specifies the runtime contexts to use.
-->
<property name="contexts" value="test, production" />
из источника: SpringLiquibase - это обновление кода, это поведение по умолчанию.
protected void performUpdate(Liquibase liquibase) throws LiquibaseException{
if (tag != null) {
liquibase.update(tag, new Contexts(getContexts()), new LabelExpression(getLabels()));
} else {
liquibase.update(new Contexts(getContexts()), new LabelExpression(getLabels()));
}
}
класс Liquibase имеет метод
public DiffResult diff(Database referenceDatabase, Database targetDatabase, CompareControl compareControl)
Таким образом, вы можете создать собственный SpringLiquibase и использовать diff вместо обновления
public class MyDiffSpringLiquibase extends SpringLiquibase {
@Override
protected void performUpdate(Liquibase liquibase) throws LiquibaseException {
Database referenceDatabase = new MySQLDatabase();
referenceDatabase.setConnection();
Database targetDatabase = new MySQLDatabase();
targetDatabase.setConnection();
CatalogAndSchema catalogAndSchemaReference = new CatalogAndSchema();
CatalogAndSchema catalogAndSchemacomparison = new CatalogAndSchema();
Set<Class<? extends DatabaseObject>> finalCompareTypes = null;
Class<? extends DatabaseObject>[] snapshotTypes = new Class[]{Table.class ,View.class......};
if (snapshotTypes != null && snapshotTypes.length > 0) {
finalCompareTypes = new HashSet<Class<? extends DatabaseObject>>(Arrays.asList(snapshotTypes));
}
CompareControl compareControl = new CompareControl(new CompareControl.SchemaComparison[]{new CompareControl.SchemaComparison(catalogAndSchemaReference, catalogAndSchemacomparison)}, finalCompareTypes);
liquibase.diff(referenceDatabase, targetDatabase, compareControl);
}
}
и зарегистрируйте его как боб
@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new MyDiffSpringLiquibase ();
liquibase.setChangeLog("classpath:db-changelog.xml");
liquibase.setDataSource(dataSource());
return liquibase;
}