Spring Boot Liquibase using best practices

 

Liquibase problem

 

As the project progresses, the amount of code in a project will be very large, but also complex database tables. If a project uses Liquibase database structure management, more and more problems will emerge.

 

  1. ChangeSet modified files at the same time many people, their ChangeSet is get rid of, or even deleted.
  2. Developers will ChangeSet added to the file has been executed, resulting in the execution order problems.
  3. Developers add unauthorized changes to business data, other environment can not be performed with an error.
  4. ChangeSet included in SQL schema name, resulting schema name when other environmental changes, ChangeSet error.
  5. Developers do not accidentally change the ChangeSet has been executed on startup error.

 

Liquibase basic norms

 

  1. Use ChangeSet id [Task ID] - [Date] - [number], as T100-20181009-001
  2. ChangeSet must fill author
  3. Liquibase prohibit traffic data sql operation
  4. Use <sql>is prohibited contains the schema name
  5. Liquibase prohibit the use of stored procedures
  6. All table, column to add remarks to annotate
  7. Has been performed in ChangeSet modification is strictly prohibited.
  8. Do not upgrade project liquibase version, especially the big version upgrade. ChangeSet MD5SUM different versions of the algorithm is not the same.

 

Other database specification will not repeat them.

 

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
    <changeSet id="T100-20181009-001" author="markfredchen" >
        <createTable tableName="demo_user" remarks="用户表">
            <column name="id" type="bigint" remarks="用户ID,主键">
                <constraints nullable="false" primaryKey="true" primaryKeyName="pk_demo_user_id"/>
            </column>
            <column name="username" type="varchar(100)" remarks="用户名">
                <constraints nullable="false"/>
            </column>
            ...
        </createTable>
    </changeSet>
</databaseChangeLog>

 

 

Effective document management

 

Use Liquibase provided <include file="xxx"/>tag, ChangeSet can be distributed in different files. At the same time <include/>support multi-level reference.
Can effectively manage projects ChangeSet based on this feature. We recommend the following specification management.

 

Be managed according to published

 

  1. Create a new folder for each release, release all the relevant documents and data ChangeSet initialization files are placed in these folders.
  2. Each release a new master.xml. In this master.xml, include this release ChangeSet file to be executed
  3. According to independent development team ChangeSet file (optional)
  4. Independent ChangeSet file according to the function. For example user.xml, company.xml

 

resources
  |-liquibase
    |-user
    | |- master.xml
    | |- release.1.0.0 | | |- release.xml | | |- user.xml -- 用户相关表ChangeSet | | |- user.csv -- 用户初始化数据 | | |- company.xml -- 公司相关表ChangeSet | |- release.1.1.0 | | |- release.xml | | |- ...

 

Modular Management

 

When the project becomes huge, a service function module may contain more and more. At this point we will find ways to be split module, step by step of micro-services. However, it will not start in the face of Liquibase ChangeSet complex.
The problem with this for the future may be faced early in the project on the right Liquibase modular management, will bring great benefits in the future.
First, explain Spring Boot in Liquibase default is how to do and the results.

 

  1. At startup, LiquibaseAutoConfiguration will be configured according to default initialization SpringLiquibase
  2. SpringLiquibase.afterPropertiesSet execution ChangeSet file () in
  3. The first run ChangeSets time, automatically creates two tables in the database databasechangeloganddatabasechangeloglock

 

So we can say that a SpringLiquibase executed as a module.

 

When introducing multi-module management, document management practices based on section, we adjusted based management module to do next.

 

resources
  |-liquibase
    |-user
    | |- master.xml
    | |- release.1.0.0 | | |- release.xml | | |- user.xml -- 用户相关表ChangeSet | | |- user.csv -- 用户初始化数据 | | |- company.xml -- 公司相关表ChangeSet | |- release.1.1.0 | | |- release.xml | | |- ... |- order | |- master.xml | |- release.1.0.0 | | |- ...

 

When the day we need to split orders into separate service module, ChangeSet file we just need to move out of the relevant module. To complete the split data structure.

 

Then how in a Spring Boot to run multiple SpringLiquibase it? The following code needs to be adjusted.

 

  1. Spring Boot disable auto-run Liquibase.

 

When the configuration is enabled, Spring Boot AutoConfigure will use the default configuration of the initialization Bean named springLiquibase. Then we do not configure it, will complain when Spring Boot start.

 

# application.properties
# spring boot 2以上
spring.liquibase.enabled=false
# spring boot 2以下 liquibase.enabled=false
  1. Spring Boot Configuration Liquibase Bean

Configuring two SpringLiquibase Bean, Bean names are userLiquibase and orderLiqubase.

@Configuration
public class LiquibaseConfiguration() {

    /**
     *  用户模块Liquibase   
     */
    @Bean
    public SpringLiquibase userLiquibase(DataSource dataSource) {
        SpringLiquibase liquibase = new SpringLiquibase();
        // 用户模块Liquibase文件路径
        liquibase.setChangeLog("classpath:liquibase/user/master.xml");
        liquibase.setDataSource(dataSource);
        liquibase.setShouldRun(true);
        liquibase.setResourceLoader(new DefaultResourceLoader());
        // 覆盖Liquibase changelog表名
        liquibase.setDatabaseChangeLogTable("user_changelog_table");
        liquibase.setDatabaseChangeLogLockTable("user_changelog_lock_table");
        return liquibase;
    }
    /**
     *  订单模块Liquibase   
     */
    @Bean
    public SpringLiquibase orderLiquibase() {
      SpringLiquibase liquibase = new SpringLiquibase();
      liquibase.setChangeLog("classpath:liquibase/order/master.xml");
      liquibase.setDataSource(dataSource);
      liquibase.setShouldRun(true);
      liquibase.setResourceLoader(new DefaultResourceLoader());
      liquibase.setDatabaseChangeLogTable("order_changelog_table");
      liquibase.setDatabaseChangeLogLockTable("order_changelog_lock_table");
      return liquibase;
    }
}

 

 

Guess you like

Origin www.cnblogs.com/zhaoyanhaoBlog/p/11327039.html