微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用带有 Spring-Boot JPA 和 Maven 的 Liquibase 来管理来自 JPA 实体的迁移

如何解决如何使用带有 Spring-Boot JPA 和 Maven 的 Liquibase 来管理来自 JPA 实体的迁移

我一直在尝试使用 liquibase 来管理 Spring JPA 项目上的迁移,就像 Python/Django 对 makemigrations 所做的那样。 Liquibase documentation 非常令人困惑,我尝试遵循我在网上找到的一些 SA 答案和教程,但都无济于事。

这是我想要做的:

  1. 通过 JPA 注释类定义实体。
  2. 生成迁移以反映 MysqL 数据库上的这些实体。
  3. 数据库上应用所述迁移。 (最初为空)

到目前为止,我能够生成一个“差异”更改日志文件,并以某种方式设法让 liquibase 在空数据库上创建 databasechangelogdatabasechangeloglock 表。但是,我无法使用差异更新 master.xml 文件或将差异应用于数据库

到目前为止,这是我的配置(基本的 spring-jpa 项目,只有一个用于测试的实体):

Pom.xml(缩写)

<project>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>my-group</groupId>
    <artifactId>web</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>15</maven.compiler.source>
        <maven.compiler.target>15</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>MysqL</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>4.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-maven-plugin</artifactId>
                <version>4.3.2</version>
                <configuration>
                    <changeLogFile>src/main/resources/db/changelog-master.xml</changeLogFile>
                    <diffChangeLogFile>src/main/resources/db/diff-changelog.xml</diffChangeLogFile>
                    <outputChangeLogFile>src/main/resources/db/out-changelog.xml</outputChangeLogFile>
                    <driver>com.MysqL.jdbc.Driver</driver>
                    <referenceUrl>hibernate:spring:my.project.model?dialect=org.hibernate.dialect.MysqL5Dialect&amp;hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&amp;hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy</referenceUrl>
                    <url>jdbc:MysqL://localhost:3306/my-db?useSSL=false</url>
                    <username>user</username>
                    <password>pass</password>
                    <outputDefaultSchema>true</outputDefaultSchema>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.liquibase.ext</groupId>
                        <artifactId>liquibase-hibernate5</artifactId>
                        <version>4.3.2</version>
                    </dependency>
                    <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-data-jpa</artifactId>
                        <version>2.4.3</version>
                    </dependency>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-beans</artifactId>
                        <version>5.3.4</version>
                    </dependency>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-core</artifactId>
                        <version>5.3.4</version>
                    </dependency>
                    <dependency>
                        <groupId>javax.validation</groupId>
                        <artifactId>validation-api</artifactId>
                        <version>2.0.1.Final</version>
                    </dependency>
                    <dependency>
                        <groupId>org.javassist</groupId>
                        <artifactId>javassist</artifactId>
                        <version>3.27.0-GA</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
</project>

application.properties

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MysqL5InnoDBDialect
spring.jpa.hibernate.ddl-auto=none
spring.datasource.driver-class-name=com.MysqL.jdbc.Driver
spring.datasource.url = jdbc:MysqL://localhost:3306/my-db?useSSL=false
spring.datasource.username = user
spring.datasource.password = pass
spring.liquibase.enabled=true
spring.liquibase.url=jdbc:MysqL://localhost:3306/my-db?useSSL=false
spring.liquibase.user=user
spring.liquibase.password=pass
spring.liquibase.change-log=classpath:db/changelog-master.xml
logging.level.org.springframework=INFO
hibernate.dialect=org.hibernate.dialect.MysqL5InnoDBDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
hibernate.generate_statistics=true

我还添加一个空的 changelog-master.xml 文件,其中包含(不包括命名空间):

<databaseChangeLog />

因此,如果我运行 spring-boot:run,它会创建这两个 databasechangelog 表。(无内容)。然后我可以运行 mvn liquibase:diff 生成一个 diff.xml 文件(尽管有一些休眠警告)。这个 diff 文件对我很有意义:

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog>
    <changeSet author="tiago (generated)" id="1618352585193-1">
        <createTable tableName="chunk">
            <column autoIncrement="true" name="id" type="BIGINT">
                <constraints nullable="false" primaryKey="true" primaryKeyName="chunkPK"/>
            </column>
            <column name="x_origin" type="BIGINT">
                <constraints nullable="false"/>
            </column>
            <column name="y_origin" type="BIGINT">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>
</databaseChangeLog>

但是现在,我该如何应用它?我如何使该 diff 命令将此特定差异“附加”到主更改日志?运行 mvn liquibase:update 什么也不做。此外,数据库上的变更日志表保持为空。

编辑: 我尝试手动将差异添加到主文件中,如下所示:

<databaseChangeLog>
    <include file="classpath:db/diff-changelog.xml" />
</databaseChangeLog>

在运行 changelogSyncupdate 后,我设法在 databasechangelog 表上获得了一条记录。但是新表并未创建。

感谢您的帮助,

解决方法

如果 Liquidbase 使您感到困惑,也许您应该考虑使用其他迁移工具。我个人使用 flyway,它非常直观且易于使用。 Flyway 只使用 SQL,这似乎很适合 MySQL。

检查一下https://flywaydb.org/

,

你可以查看我写的这个演示:https://github.com/AlexeyGorelik/liquibase-demo

这里我使用纯 liquibase core-lib 和 .xml 方法(个人更喜欢 .yml,因为它对我来说更具可读性)。

如何运行:

  1. 运行 DemoApplication 类,Liquibase bean 将完成剩下的工作。
  2. 通过 http://localhost:8080/customer/1 检查实体是否存在

不要忘记检查数据库连接属性!

.sql 文件的文档:https://docs.liquibase.com/change-types/community/sql-file.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。