当前位置: 首页 > 知识库问答 >
问题:

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

穆俊哲
2023-03-14

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

我还创建了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个答案

白弘伟
2023-03-14

这是Spring bean配置:

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

以及[liquibase-web站点][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" />  

来源: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;
}
江建明
2023-03-14

你必须使用liquibase插件来实现maven或gradle,这取决于你在构建中使用的是什么。

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

如果您使用的是gradle,则liquibase插件在调用差异日志时无法顺利工作。

根据这个答案,创建一个名为liquibase的文件。格雷德尔。我已经按照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:“液化”。在你的构建中使用gradle'。格雷德尔

现在,要生成diffChangeLog,请调用gradle liquibaseDiffChangelog

请注意,该示例使用Spring boot的类之一作为Hibernate物理命名策略。您可以通过参考此答案来创建自己的实现。

 类似资料:
  • 我无法从Spring Boot项目的JPA实体生成初始更改日志。我的pom.xml如下: 下面是液化酶。属性文件: 当我运行命令时 它在DB[Full log on Pastebin]的

  • 问题内容: 我正在尝试从现有的空数据库中生成symfony2中的实体(相当大,从头开始创建实体确实很痛苦)。不幸的是,我遇到了很大的问题。 当我尝试调用以下命令时(在Windows上如果发生任何更改): 我收到以下消息: 没有要处理的元数据类。 发布之前,我已经: 验证我的配置正常(我可以连接到数据库), 我的捆绑软件已创建,上面指定的路径有效 当我尝试转换为xml / yml时,与尝试生成注释映

  • 我在spring-boot应用程序中为数据库配置了以下liquibase配置。 最初,这些YAML脚本是在应用程序启动和数据库创建时执行的,现在我想更新一列的数据类型,所以我需要更新现有的创建表。列配置的YAML,或者需要创建另一个具有不同名称的文件,并将条目添加到“db.changelog-master.yaml”文件中。 请建议,谢谢

  • 我正在评估JHipster并测试它如何处理数据库DDL修改。在我的测试中,我创建了一个Jhipster项目,然后运行。JHipster生成了所有的集成测试,一切看起来都很好。所以我开始投入生产。但后来我意识到我在一组实体之间定义了错误的关系。原始的文件声明了一个关系。 为了修复这种关系,我尝试了三种方法。首先,我试图纠正文件中的关系,并重新运行。这做了我需要的正确更改,除了它覆盖了liquibas

  • 我有生成Hibernate实体的mysql db,现在我需要从这些实体生成内存数据库进行测试。我在试图运行我的单元测试时遇到了这个错误。 /***主]o.h.发动机。jdbc。spi。SqlExceptionHelper:SQL错误:42102,SQLState:42S02 2016-02-16 18:10:47.864错误29758---[main]o.h.engine。jdbc。spi。Sql

  • 我正在开发一款基于IQ水平问题的android应用程序。我想上传到游戏商店。该应用程序由50多个级别组成。每个级别由9个问题组成。我对我的应用程序将使用哪个数据库感到困惑。