0Liquibase安全地发展您的数据库架构


1.概述

在本快速教程中,我们将利用Liquibase来改进 Java Web应用程序的数据库模式。

我们将首先关注一般的Java应用程序,我们还将重点关注一些可用于Spring和Hibernate的有趣选项。

简单地说,使用Liquibase的核心是在更新日志文件 -即跟踪需要运行更新数据库的所有更改的XML文件。

让我们从我们需要添加到pom.xml中的Maven依赖开始:

<dependency>
    <groupId>org.liquibase</groupId>
     <artifactId>liquibase-core</artifactId>
      <version>3.4.1</version>
</dependency>

2.数据库更改日志

现在,让我们看一个简单的changeLog文件 - 这个文件只在表“ users ”中添加了一个列“ 地址 ”:

<databaseChangeLog
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext
   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
   http://www.liquibase.org/xml/ns/dbchangelog
   http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">

    <changeSet author="John" id="someUniqueId">
        <addColumn tableName="users">
            <column name="address" type="varchar(255)" />
        </addColumn>
    </changeSet>

</databaseChangeLog>

请注意更改集如何由ID和作者标识- 以确保它可以唯一标识并仅应用一次。

让我们看看如何将它连接到我们的应用程序中,并确保它在应用程序启动时运行。

3.使用Spring Bean运行Liquibase

我们在应用程序启动时运行更改的第一个选项是通过Spring bean。当然还有很多其他方法,但是如果我们正在处理Spring应用程序 - 这是一个很好的,简单的方法:

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

注意我们如何将它指向需要存在于类路径上的有效changeLog文件。

4.使用Liquibase和Spring Boot

如果您使用的是Spring Boot,则无需为Liquibase 定义Bean。

您只需将更改日志放在“ db / changelog / db.changelog-master.yaml ”中,Liquibase迁移将在启动时自动运行。

注意:

  • 您需要添加“ liquibase-core ”依赖项。
  • 您可以使用“ liquibase.change-log ”属性更改默认更改日志文件- 例如:
liquibase.change-log=classpath:liquibase-changeLog.xml

5. 使用Maven插件生成changeLog

而不是手动编写changeLog文件 - 我们可以使用Liquibase Maven插件生成一个并为自己节省大量工作。

5.1。插件配置

以下是对pom.xml的更改:

<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>3.4.1</version>
</dependency>
...
<plugins>
    <plugin>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-maven-plugin</artifactId>
        <version>3.4.1</version>
        <configuration>                  
            <propertyFile>src/main/resources/liquibase.properties</propertyFile>
        </configuration>                
    </plugin>
</plugins>

5.2。从现有数据库生成changeLog

我们可以使用插件从现有数据库生成changeLog:

mvn liquibase:generateChangeLog

以下是liquibase属性:

url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
outputChangeLogFile=src/main/resources/liquibase-outputChangeLog.xml

最终结果是changeLog文件,我们可以使用它来创建初始数据库模式或填充数据。以下是我们的示例应用程序的外观:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog ...>

    <changeSet author="John (generated)" id="1439225004329-1">
        <createTable tableName="APP_USER">
            <column autoIncrement="true" name="id" type="BIGINT">
                <constraints primaryKey="true"/>
            </column>
            <column name="accessToken" type="VARCHAR(255)"/>
            <column name="needCaptcha" type="BIT(1)">
                <constraints nullable="false"/>
            </column>
            <column name="password" type="VARCHAR(255)"/>
            <column name="refreshToken" type="VARCHAR(255)"/>
            <column name="tokenExpiration" type="datetime"/>
            <column name="username" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="preference_id" type="BIGINT"/>
            <column name="address" type="VARCHAR(255)"/>
        </createTable>
    </changeSet>
    ...
</databaseChangeLog>

5.3。从两个数据库之间的diff 生成changeLog

我们可以使用插件从两个现有数据库之间的差异生成changeLog文件(例如:开发和生产):

mvn liquibase:diff

以下是属性:

changeLogFile=src/main/resources/liquibase-changeLog.xml
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
referenceUrl=jdbc:h2:mem:oauth_reddit
diffChangeLogFile=src/main/resources/liquibase-diff-changeLog.xml
referenceDriver=org.h2.Driver
referenceUsername=sa
referencePassword=

这是生成的changeLog的片段:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog ...>
    <changeSet author="John" id="1439227853089-1">
        <dropColumn columnName="address" tableName="APP_USER"/>
    </changeSet>
</databaseChangeLog>

这是一种发展数据库的超级强大方法 - 例如 - 允许Hibernate自动生成用于开发的新模式,然后将其用作针对旧模式的参考点。

6.使用Liquibase Hibernate插件

如果应用程序使用Hibernate - 我们将看一个生成changeLog的非常有用的方法。

第一-在这里是如何的liquibase-休眠插件应在Maven的配置:

6.1。插件配置

首先,让我们配置新插件并使用正确的依赖项:

<plugins>
    <plugin>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-maven-plugin</artifactId>
        <version>3.4.1</version>
        <configuration>                  
            <propertyFile>src/main/resources/liquibase.properties</propertyFile>
        </configuration>
        <dependencies>
            <dependency>
                <groupId>org.liquibase.ext</groupId>
                <artifactId>liquibase-hibernate4</artifactId>
                <version>3.5</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>4.1.7.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.data</groupId>
                <artifactId>spring-data-jpa</artifactId>
                <version>1.7.3.RELEASE</version>
            </dependency>
        </dependencies>               
    </plugin>
</plugins>

6.2。 从数据库和持久性实体之间的差异生成changeLog

现在是有趣的部分。我们可以使用此插件从现有数据库(例如生产)和新的持久性实体之间的差异生成changeLog文件。

所以 - 简单化 - 一旦修改了实体,您就可以简单地针对旧的数据库模式生成更改,从而获得一种干净,强大的方法来在生产中发展您的模式。

以下是liquibase属性:

changeLogFile=classpath:liquibase-changeLog.xml
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
referenceUrl=hibernate:spring:org.baeldung.persistence.model
  ?dialect=org.hibernate.dialect.MySQLDialect
diffChangeLogFile=src/main/resources/liquibase-diff-changeLog.xml

注意:referenceUrl正在使用包扫描,因此需要dialect参数。