Spring Boot的数据库迁移

 

参考:

https://blog.csdn.net/u010963948/article/details/77801431  

https://blog.csdn.net/linxingliang/article/details/81145864

FlyWay

一,首先我先了解下FlyWay是如何运转的。

最简单的方案是将Flyway指向一个空数据库。
这里写图片描述
它将尝试找到其元数据表。当数据库为空时,Flyway将不会找到它, 而是创建它。您现在拥有一个名为SCHEMA_VERSION的单个空表的数据库 :
这里写图片描述
该表将用于跟踪数据库的状态。之后,Flyway将开始扫描应用程序的文件系统或类路径进行迁移。它们可以用Sql或Java编写。
然后根据其版本号对迁移进行排序,并按顺序应用:
这里写图片描述
随着应用每个迁移,元数据表将相应更新:
schema_version
这里写图片描述
随着元数据和初始状态的到位,我们现在可以谈论迁移到较新的版本。
Flyway将再次扫描应用程序的文件系统或类路径进行迁移。根据元数据表检查迁移。如果版本号低于或等于标记为当前版本的版本号,则忽略它们。
剩余的迁移是挂起的迁移:可用但未应用。
这里写图片描述
然后,他们通过版本号进行排序,并依次执行:
这里写图片描述
该元数据表进行更新,因此:
schema_version

就是这样!每当需要发展数据库时,无论是结构(DDL)还是参考数据(DML),只需创建一个版本号高于当前版本的新迁移。下一次Flyway启动时,它会发现并相应地升级数据库。
二,FlyWay在SpingBoot的使用

一种途径是通过Spring Boot的spring.jpa.hibernate.ddl-auto属性将hibernate.hbm2ddl.auto属性设置为create、 create-drop或update。例如,要把hibernate.hbm2ddl.auto设置为create-drop,我们可以在application.yml里加入如下内容:

spring:
    jpa:
        hibernate:
            ddl-auto: create-drop

   然而,这对生产环境来说并不理想,因为应用程序每次重启数据库, Schema就会被清空,从头开始重建。它可以设置为update,但就算这样,我们也不建议将其用于生产环境。
还有一个途径。我们可以在schema.sql里定义Schema。在第一次运行时,这么做没有问题,但随后每次启动应用程序时,这个初始化脚本都会失败,因为数据表已经存在了。这就要求在书写初始化脚本时格外注意,不要重复执行那些已经做过的工作。
一个比较好的选择是使用数据库迁移库(database migration library)。它使用一系列数据库脚本,而且会记录哪些已经用过了,不会多次运用同一个脚本。应用程序的每个部署包里都包含了这些脚本,数据库可以和应用程序保持一致。Spring Boot为两款流行的数据库迁移库提供了自动配置支持。
 Flyway(http://flywaydb.org)
 Liquibase(http://www.liquibase.org)
当你想要在Spring Boot里使用其中某一个库时,只需在项目里加入对应的依赖,然后编写脚本就可以了。让我们先从Flyway开始了解吧。
1. 用Flyway定义数据库迁移过程
Flyway是一个非常简单的开源数据库迁移库,使用SQL来定义迁移脚本。它的理念是,每个脚本都有一个版本号, Flyway会顺序执行这些脚本,让数据库达到期望的状态。它也会记录已执行的脚本状态,不会重复执行。在阅读列表应用程序这里,我们先从一个没有数据表和数据的空数据库开始。因此,这个脚
本里需要先创建Reader和Book表,包含外键约束和初始化数据。代码清单8-2就是从空数据库到
可用状态的Flyway脚本。
Flyway数据库初始脚本

create table Reader (
id serial primary key,
username varchar(25) unique not null,
password varchar(25) not null,
fullname varchar(50) not null
);
create table Book (
id serial primary key,
author varchar(50) not null,
description varchar(1000) not null,
isbn varchar(10) not null,
title varchar(250) not null,
reader_username varchar(25) not null,
foreign key (reader_username) references Reader(username)
);
create sequence hibernate_sequence;
insert into Reader (username, password, fullname)
values ('craig', 'password', 'Craig Walls');

如你所见, Flyway脚本就是SQL。让其发挥作用的是其在Classpath里的位置和文件名。Flyway脚本都遵循一个命名规范,含有版本号,具体如图8-1所示。
这里写图片描述
所有Flyway脚本的名字都以大写字母V开头,随后是脚本的版本号。后面跟着两个下划线和对脚本的描述。因为这是整个迁移过程中的第一个脚本,所以它的版本是1。描述可以很灵活,主要用来帮助理解脚本的用途。稍后我们需要向数据库添加新表,或者向已有数据表添加新字段。可以再创建一个脚本,标明版本号为2。Flyway脚本需要放在相对于应用程序Classpath根路径的/db/migration路径下。因此,项目中,
脚本需要放在src/main/resources/db/migration里。你还需要将spring.jpa.hibernate.ddl-auto设置为none,由此告知Hibernate不要创建数据表。这关系到application.yml中的如下内容:

spring:
    jpa:
        hibernate:
            ddl-auto: none

剩下的就是将Flyway添加为项目依赖。在Gradle里,此依赖是这样的:
compile(“org.flywaydb:flyway-core”)
在Maven项目里, 是这样的:

<dependency>
<groupId>org.flywayfb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>

 

在应用程序部署并运行起来后, Spring Boot会检测到Classpath里的Flyway,自动配置所需的
Bean。 Flyway会依次查看/db/migration里的脚本,如果没有执行过就运行这些脚本。每个脚本都
执行过后,向schema_version表里写一条记录。应用程序下次启动时,Flyway会先看schema_version
里的记录,跳过那些脚本。

Liquibase

 

说明:

(1)Spring Boot 版本:1.5.12.RELEASE

(2)Liquibase版本:3.5.5

 

前言:

在前面几节介绍了Flyway,这节就介绍下Liquibase。

 

一、什么是Liquibase?

官网地址:http://www.liquibase.org

LiquiBase是一个用于数据库重构和迁移的开源工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。

 

二、Liquibase的特点?

Liquibase的主要特点有:

(1)支持几乎所有主流的数据库,如MySQL, PostgreSQL, Oracle, Sql Server, DB2等;
(2)支持多开发者的协作维护;
(3)日志文件支持多种格式,如XML, YAML, JSON, SQL等;

(4)支持多种运行方式,如命令行、Spring集成、Maven插件、Gradle插件等;

 

 

三、Liquibase在Sping Boot的使用

 

3.1 新建一个项目

       新建项目,取名为:springboot-liquibase

3.2 添加依赖

       在pom.xml文件中添加依赖:

   

<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.kfit</groupId>
        <artifactId>springboot-liquibase</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
        <name>springboot-liquibase</name>
        <description>Demo project for Spring Boot</description>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.12.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </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.liquibase</groupId>
                <artifactId>liquibase-core</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </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>
            </plugins>
        </build>
    </project>

 

说明:

(1)Liquibase的依赖是:liquibase-core;

(2)为什么需要配置JPA和MySQL驱动:默认情况下,Liquibase会自动注入注解了@Primary的DataSource,那么这个数据源是哪来的呢?那这里就是使用了JPA了(当然你可以使用jdbcTemplate或者是MyBatis);由于我们使用mysql数据库进行测试,那么就需要引入MySQL驱动了。

 

3.3 添加配置

       在application.properties文件添加配置:

    ### datasource
    spring.datasource.platform=mysql
    spring.datasource.url = jdbc:mysql://localhost:3306/liquibase_test
    spring.datasource.username = root
    spring.datasource.password = root
    spring.datasource.driverClassName = com.mysql.jdbc.Driver
    ### jpa
    spring.jpa.database = MYSQL
    spring.jpa.show-sql = true
    spring.jpa.hibernate.ddl-auto = none

       这个没什么好说的,就是数据源和jpa的基本配置。

3.4 Liquibase存放路径说明

       默认情况下是db/changelog,但你能够使用liquibase.change-log进行修改。这里我们由于在接下里的测试中使用的是SQL的方式,所以需要修改下。为了接下里的测试,在resources创建目录db/changelog:

src/main/resources

       - db

              -- changelog

       其次在application.properties中添加配置:

### liquibase

liquibase.change-log=classpath:/db/changelog/db.changelog-master.sql

 

3.5 Liquibase sql脚本命令规则

       对于Liquibase的脚本db.changelog-master.sql(这里也是.xml或者是.yaml)如果使用的xml的话,那么在上面的配置中需要做下调整。

 

3.6 测试一

       db/changelog下新建文件db.changelog-master.sql,脚本如下:

   
 

   --liquibase formatted sql
   --changeset andy:1.1
   CREATE TABLE book (
      id  int UNSIGNED NOT NULL AUTO_INCREMENT,
      name  varchar(255) NULL,
      createTime  datetime NULL ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    );

 

说明:

(1)--liquibase formatted sql:代表使用格式化的sql;

(2)--changeset andy:1.1:andy代表作者,1.1代表id,也就是版本号,这里没有大小之后,Liquibase是按照顺序执行的。

运行应用,查看数据库中是否多了三个表:

其一是book表,这是我们脚本中创建的,其二是Liquibase版本管理的表DATABASECHANGELOG和DATABASECHANGELOGLOCK。其中DATABASECHANGELOG是每个版本的日志表,DATABASECHANGELOGLOCK是日志锁表。

 

3.7 测试二

       在db.changelog-master.sql下追加脚本(Liquibase的升级版本配置是在同一个文件里的),如下:

    --changeset andy:1.2
    INSERT INTO book(name, createTime) VALUES ('从零开始学Spring Boot', '2018-04-21 16:53:48');

 

       当前整个文件看起来是这样子的:

   

     --liquibase formatted sql
    --changeset andy:1.1
    CREATE TABLE book (
      id  int UNSIGNED NOT NULL AUTO_INCREMENT,
      name  varchar(255) NULL,
      createTime  datetime NULL ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    );
     --changeset andy:1.2


   
    INSERT INTO book(name, createTime) VALUES ('从零开始学Spring Boot', '2018-04-21 16:53:48');

 

运行应用,查看book表中是否多了条数据,DATABASECHANGELOG是否多了条版本记录。

 

       到此为止,Liquibase的使用就一切顺利了,到这里就告一段落了。

 

 

「SpringCloud视频」最近更新:

 

    24. 覆写Feign的默认配置Configuration之Contract
    25. Spring Cloud中关于Feign的常见问题总结
    26. 解决Spring Cloud中FeignRibbon第一次请求失败的方法
    27. Feign添加 fallbackFactory 属性来触发请求进行容灾降级
    28. 断路器Hystrix总结
    29. Health Indicator(健康指标) 和metrics stream(指标流)
    30. 断路器监控(Hystrix Dashboard)
    31. 断路器聚合监控(turbine)

 SpringCloud视频:http://t.cn/R3QeRZc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值