如何使用liquibase从spring中的数据库和持久性实体之间的差异生成更改日志?

时间:2017-07-01 16:03:21

标签: spring hibernate liquibase liquibase-hibernate

请在Spring(基于JAVA的配置)中解决上述问题,而不是在春季启动时。 我在网上找到的大多数教程都基于spring boot,但是我的应用程序没有在spring boot上运行, 只是春天的mvc。 我已经在我的类路径中有必要的依赖项,即liquibase-core-3.5.3和liquibase-hibernate5-3.6 jar。

我还创建了liquibase属性文件(在类路径中),如下所示

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 个答案:

答案 0 :(得分:0)

这是spring bean config:

@Bean
public SpringLiquibase liquibase() {
    SpringLiquibase liquibase = new SpringLiquibase();
    liquibase.setChangeLog("classpath:db-changelog.xml");
    liquibase.setDataSource(dataSource());
    return liquibase;
}
来自[liquibase - web site] [1]

和xml配置

<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" />  

来自source: 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而不是update

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

@Bean
public SpringLiquibase liquibase() {
    SpringLiquibase liquibase = new MyDiffSpringLiquibase ();
    liquibase.setChangeLog("classpath:db-changelog.xml");
    liquibase.setDataSource(dataSource());
    return liquibase;
}

答案 1 :(得分:0)

您必须使用liquibase插件为maven或gradle执行此操作,具体取决于您用于构建的内容。

Maven plugin是关于如何运行liquibase命令的非常好的文档。

如果您使用的是gradle,liquibase插件在调用diffChangeLog时无法顺利运行。

根据this answer,创建名为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

请注意该示例使用spring boot的类之一作为Hibernate Physical Naming Strategy。您可以参考this answer

创建自己的实现