https://segmentfault.com/a/1190000010526452

在执行数据库迁移时,我们推荐使用jOOQ与Flyway - 数据库迁移轻松。 在本章中,我们将简单的来使用这两个框架。

一、Flyway简介

什么是Flyway

Flyway是独立于数据库的应用、管理、跟踪数据库变更的数据库版本管理工具。
Flyway的项目主页是:https://flywaydb.org/

为什么使用Flyway

  • 不同的开发人员在开发产品特性时,都有可能更新数据库(添加新表,新的约束等)。当开发人员完成工作并提交代码时,代码会被合并到主分支并在测试服务器上执行单元测试与集成测试。我们在哪个环节来执行数据库的更新操作呢?由QA 部门手工执行sql 脚本?或者我们开发一断程序自动执行数据库更新?以什么顺序来执行这些更新脚本?这些问题同样存在于生产环境。

  • 我们的产品部署在不同的客户服务器上,以及很多的测试、联调、实验局、销售环境上。不同的客户和测试环境上都部署着不同版本的产品。当他们需要升级他们的产品到新的版本时,我们不仅需要让他们的管理员可以升级产品到新的版本,同时需要保留他们的已有数据。在升级产品的步骤中,我们清楚地知道客户数据库的当前版本,以及需要在该数据库上执行哪些数据库更新脚本,来更新数据库表结构与数据库中已存在的数据。当升级完成时,数据库表结构及数据应当与升级后的产品版本保持一致。

  • 当升级失败时(比如在升级过程中出现网络连接失败),我们应当支持对失败进行修复。

更多Flyway文章(参考以下文档)

二、Maven配置Flyway和jOOQ插件

properties

<!-- 数据库信息 -->
<db.url>jdbc:mysql://127.0.0.1:33006/flyway_test?useUnicode=true&amp;characterEncoding=UTF-8</db.url>
<db.username>root</db.username>
<db.password>123456</db.password>

plugins

<!-- Flyway插件 -->
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>3.0</version>
<!-- 在代码生成时候执行Flyway插件 -->
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>migrate</goal>
</goals>
</execution>
</executions>
<!-- 指定Flyway迁移脚本文件目录 -->
<configuration>
<url>${db.url}</url>
<user>${db.username}</user>
<password>${db.password}</password>
<locations>
<location>filesystem:src/main/resources/db/migration</location>
</locations>
</configuration>
</plugin> <!-- jOOQ代码生成插件 -->
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>${jooq.version}</version>
<executions>
<execution>
<id>java-generator</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<jdbc>
<url>${db.url}</url>
<user>${db.username}</user>
<password>${db.password}</password>
</jdbc>
<generator>
<database>
<name>org.jooq.util.mysql.MySQLDatabase</name>
<includes>.*</includes>
<inputSchema>flyway_test</inputSchema>
</database>
<target>
<packageName>test.generated</packageName>
<directory>target/generated-sources/jooq-mysql-java</directory>
</target>
</generator>
</configuration>
</execution>
</executions>
</plugin>

三、数据库增量脚本

假设已经插件MySQL数据库:flyway_test

src/main/resources/db/migration目录(Flyway插件指定的location目录)下插件创建脚本文件:

  • V1__create_author.sql

  • V2__create_book.sql

这三个脚本按照版本V[1,2,3...]创建,这是脚本的内容:

# V1__create_author.sql
CREATE TABLE `author` (
`id` int NOT NULL,
`first_name` varchar(255) DEFAULT NULL,
`last_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO author VALUES (1, 'George', 'Orwell');
INSERT INTO author VALUES (2, 'Paulo', 'Coelho');
# V2__create_book.sql
CREATE TABLE `book` (
`id` int NOT NULL,
`author_id` int NOT NULL,
`title` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO book VALUES (1, 1, '1984');
INSERT INTO book VALUES (2, 1, 'Animal Farm');
INSERT INTO book VALUES (3, 2, 'O Alquimista');
INSERT INTO book VALUES (4, 2, 'Brida');

四、数据库迁移 & jOOQ代码生成

执行Maven构建代码时候,上一步的V1/V2脚本Flyway会按照版本顺序去执行,并由jOOQ生成Java代码:

mvn clean install

成功后,新建测试用例测试:

import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL; import java.sql.Connection;
import java.sql.DriverManager; import static test.generated.tables.Author.AUTHOR; /**
* 测试类
*/
public class Main {
public static void main(String[] args) {
// 用户名
String userName = "root";
// 密码
String password = "123456";
// mysql连接url
String url = "jdbc:mysql://127.0.0.1:33006/flyway_test?useUnicode=true&characterEncoding=UTF-8"; // Connection is the only JDBC resource that we need
// PreparedStatement and ResultSet are handled by jOOQ, internally
try (Connection conn = DriverManager.getConnection(url, userName, password)) {
DSLContext create = DSL.using(conn, SQLDialect.MYSQL);
Result<Record> result = create.select().from(AUTHOR).fetch(); for (Record r : result) {
Integer id = r.getValue(AUTHOR.ID);
String firstName = r.getValue(AUTHOR.FIRST_NAME);
String lastName = r.getValue(AUTHOR.LAST_NAME); /**
* 控制台输出
* ID: 1 first name: George last name: Orwell
* ID: 2 first name: Paulo last name: Coelho
*/
System.out.println("ID: " + id + " first name: " + firstName + " last name: " + lastName);
} // 关闭连接对象
conn.close();
}
// For the sake of this tutorial, let's keep exception handling simple
catch (Exception e) {
e.printStackTrace();
}
}
}

五、数据库变动

近期书库里多了中文书籍,需要为book表添加语言种类字段

src/main/resources/db/migration目录下新增修改数据库脚本:

# V3__book_add_language.sql
ALTER TABLE `book` ADD COLUMN `language_id` int(7) DEFAULT '1' NOT NULL;

重新运行Maven构建:

mvn clean install

测试用例:

import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.SQLDialect;
import org.jooq.impl.DSL; import java.sql.Connection;
import java.sql.DriverManager; import static test.generated.tables.Author.AUTHOR;
import static test.generated.tables.Book.BOOK; /**
* 测试类
*/
public class BookMain {
public static void main(String[] args) {
// 用户名
String userName = "root";
// 密码
String password = "123456";
// mysql连接url
String url = "jdbc:mysql://127.0.0.1:33006/flyway_test?useUnicode=true&characterEncoding=UTF-8"; // Connection is the only JDBC resource that we need
// PreparedStatement and ResultSet are handled by jOOQ, internally
try (Connection conn = DriverManager.getConnection(url, userName, password)) {
DSLContext create = DSL.using(conn, SQLDialect.MYSQL);
Result<Record> result = create.select().from(BOOK).fetch(); for (Record r : result) {
Integer id = r.getValue(BOOK.ID);
String firstName = r.getValue(BOOK.TITLE);
Integer languageId = r.getValue(BOOK.LANGUAGE_ID); /**
* 控制台输出
* ID: 1 title: 1984 language: 英文
* ID: 2 title: Animal Farm language: 英文
* ID: 3 title: O Alquimista language: 英文
* ID: 4 title: Brida language: 英文
*/
System.out.println("ID: " + id + " title: "
+ firstName + " language: " + (languageId.intValue() == 1 ? "英文" : "中文"));
} // 关闭连接对象
conn.close();
}
// For the sake of this tutorial, let's keep exception handling simple
catch (Exception e) {
e.printStackTrace();
}
}
}

【jOOQ中文】教程代码都会放在码云,希望多多宣传给Star(^_−)☆。

[jOOQ中文]3. 数据库版本管理工具Flyway的更多相关文章

  1. 数据库版本管理工具--Flyway的使用

    软件开发正常流程是:开发环境 ---> 测试环境  ----> 产环境 在开发过程中经常需要变更数据库: 表结构变更. 基础数据变更. 最直接的做法是:用客户端连上数据库直接修改. 依次修 ...

  2. 数据库版本管理工具Flyway(4.0.3)---介绍(译文)

    Flyway Evolve your Database Schema easily and reliably across all your instances 简单的.可靠的升级(发展)你的数据库模 ...

  3. 数据库版本管理工具Flyway——基础篇

    Flyway 默认规约 SQL 脚本文件默认位置是项目的源文件夹下的db/migration 目录. Java 代码默认位于db.migration 包. SQL 脚本文件及Java 代码类名必须遵循 ...

  4. 数据库版本管理工具Flyway(4.0.3)---工作机制(译文)

    How Flyway works The easiest scenario is when you point Flyway to an empty database. 最容易的方案是Flyway指向 ...

  5. 数据库版本管理工具flyway

    引入flyway_core  jar包 java 代码实现 public class FlywayMigration { @Resource private DataSource dataSource ...

  6. 【flyway】开源的数据库版本管理工具【migration】

    开源的数据库版本管理工具[migration] 记录

  7. 在SpringBoot中使用flyway进行数据库版本管理

    本文大纲 flyway是什么 能帮助我们解决什么问题 springboot环境下使用flyway flyway的工作原理 一.flyway是什么 Flyway是一个开源的数据库版本管理工具,并且极力主 ...

  8. Java敏捷数据库迁移框架——Flyway

    1.引言 想到要管理数据库的版本,是在实际产品中遇到问题后想到的一种解决方案,当时各个环境的数据库乱作一团,没有任何一个人(开发.测试.维护人员)能够讲清楚当前环境下的数据库是哪个版本,与哪个版本的应 ...

  9. 使用alembic进行数据库版本管理

    前言 随着项目业务需求的不断变更,数据库的表结构修改难以避免,此时就需要对数据库的修改加以记录和控制,便于项目的版本管理和随意的升级和降级. Alembic就可以很好的解决这个问题.Alembic是S ...

随机推荐

  1. hdu1847sg函数

    刚开始因为没注意到f是从0开始的导致wa了几次,f遍历的时候从0到f[j]<=i 这个题只有一个子情况,求出sg值直接判断就好了 #include<map> #include< ...

  2. uva-1636-概率

    https://vjudge.net/problem/UVA-1636 给出一个左轮手枪的弹夹串,第一枪是空的,问是继续打还是转一转再打下一枪还为空的概率大.继续打为空的概率就是 '00'的个数比上' ...

  3. Python+Flask+MysqL的web建设技术过程

    一.前言(个人学期总结) 个人总结一下这学期对于Python+Flask+MysqL的web建设技术过程的学习体会,Flask小辣椒框架相对于其他框架而言,更加稳定,不会有莫名其妙的错误,容错性强,运 ...

  4. C# 对json对象嵌套数组

    看图: 这里可以看到是二层嵌套!!使用C#如何实现?? 思路:使用list集合实现 → 建立类 → list集合 → 微软的   Newtonsoft.Json  (一款.NET中开源的Json序列化 ...

  5. 关于React setState的实现原理(一)

    前言 首先在学习react的时候就对setSate的实现有比较浓厚的兴趣,那么对于下边的代码,可以快速回答吗? class Root extends React.Component { constru ...

  6. iOS-----使用AddressBook添加联系人

    使用AddressBook添加联系人 添加联系人的步骤如下: 1 创建ABAddressBookRef,这就得到了对地址簿的引用. 2 调用ABPersonCreate()函数创建一个空的ABReco ...

  7. C语言——第四次作业(2)

    作业要求一 项目wordcount 设计思路:输入需统计的文件名,打开此文件,输入功能对应的字符,分别实现对应的功能,关闭文件. 主要代码 #include<stdio.h> #inclu ...

  8. ZetCode PyQt4 tutorial Dialogs

    #!/usr/bin/python # -*- coding: utf-8 -*- """ ZetCode PyQt4 tutorial In this example, ...

  9. PTA编程总

    7-1 币值转换 (20 分) 输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式.如23108元,转换后变成“贰万叁仟壹百零捌”元.为了简化输出,用小写英文字 ...

  10. Error in WCF client consuming Axis 2 web service with WS-Security UsernameToken PasswordDigest authentication scheme

    13down votefavorite 6 I have a WCF client connecting to a Java based Axis2 web service (outside my c ...