Mybatis migration使用初探

持續交付項目中,項目會不斷的迭代上線,這是會出現數據庫的改動問題。在一個還未上線的項目中,我更改數據庫可以使用簡單的直接對sql進行更改,但是面對一個已投入使用的系統而言,每次部署都對數據庫進行init顯得有點不太可能。於是便有了數據庫Migration的誕生。

我所在的項目是SpringMVC配合Mybatis的開發框架。作爲一個數據庫集成框架,Mybatis在使用上還是比較方便的。言歸正傳,爲了項目需要,於是便開始了Mybatis Migration的初探,文章中出現的不妥之處還請大家不吝賜教。

Mybatis Migration 安裝

安裝過程主要參照Mybatis的官網: http://mybatis.github.io/migrations/index.html,以及Mybatis源代碼授權地址: https://github.com/mybatis/migrations,參照github上的README文件可以輕易的完成其安裝過程。README文件中所有的Mybatis包可以直接在其Git repo的releases中找到,我選擇了3.2.0進行下載安裝。安裝完成後就可以直接在terminal中運行migrate相關的命令了。

Mybatus Migration 初始化

minggong:migration-test minggong$ migrate init
------------------------------------------------------------------------
-- MyBatis Migrations - init
------------------------------------------------------------------------
Initializing: .
Creating: environments
Creating: scripts
Creating: drivers
Creating: README
Creating: development.properties
Creating: bootstrap.sql
Creating: 20140817132704_create_changelog.sql
Creating: 20140817132705_first_migration.sql
Done!

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 2s
-- Finished at: Sun Aug 17 18:57:05 GMT+05:30 2014
-- Final Memory: 3M/493M
------------------------------------------------------------------------
minggong:migration-test minggong$ ls
README      drivers     environments    scripts

初始化之後的目錄下面會自動生成一些和Migration相關的項目文件及目錄 README, drivers, environments, scripts。drivers中放置連接數據庫需要的jdbc,environments主要放置連接數據庫的地址以及授權信息等,scripts目錄下則放置數據庫相關的sql,init的時候就已經生成了上述顯示的create_changelog.sql和first_migration.sql文件。

爲了以實例說明問題,本次測試採用了mysql數據庫,從mysql官網下載了mysql-connector-java-5.1.32,並對environment的數據庫信息進行了簡單的配置,配置如下:

## JDBC connection properties.
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/arctic
username=root
password=

這裏的arctic是已經存在本地的一個mysql數據庫。

Migrate bootstrap

minggong:migration-test minggong$ migrate bootstrap
------------------------------------------------------------------------
-- MyBatis Migrations - bootstrap
------------------------------------------------------------------------
========== Applying: bootstrap.sql =============================================

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 19:43:29 GMT+05:30 2014
-- Final Memory: 11M/493M
------------------------------------------------------------------------

運行之後,scripts文件中將會生成另外一個bootstrap文件。主要可以進行一些數據庫初始化工作。

Migrate new

new命令能夠創建新的sql腳本,我們只需要填充數據表結構信息,便可以方便的創建我們所需的數據表

minggong:migration-test minggong$ migrate new "create blog table"
------------------------------------------------------------------------
-- MyBatis Migrations - new
------------------------------------------------------------------------
Creating: 20140817142201_create_blog_table.sql
Done!

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 1s
-- Finished at: Sun Aug 17 19:52:01 GMT+05:30 2014
-- Final Memory: 3M/493M
------------------------------------------------------------------------

scripts文件夾中會創建帶有時間戳的sql文件:20140817142201_create_blog_table.sql, 其內容如下:

-- // create blog table
-- Migration SQL that makes the change goes here.

-- //@UNDO
-- SQL to undo the change goes here.

文件內容主要包含create tableundo,分別表示表的創建和刪除命令:

-- // create blog table
-- Migration SQL that makes the change goes here.
CREATE TABLE BLOG (
  ID INT,
  NAME VARCHAR(255),
  PRIMARY KEY(ID)
);
-- //@UNDO
-- SQL to undo the change goes here.
DROP TABLE BLOG;

已經將表結構寫在了sql裏面,那麼怎樣執行這個腳本,從而改變數據庫中的表結構呢。首先我們需要了解當前數據庫的狀態。

Migrate status

minggong:migration-test minggong$ migrate status
------------------------------------------------------------------------
-- MyBatis Migrations - status
------------------------------------------------------------------------
ID             Applied At          Description
================================================================================
20140817132704    ...pending...    create changelog
20140817132705    ...pending...    first migration
20140817142201    ...pending...    create blog table

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 20:21:06 GMT+05:30 2014
-- Final Memory: 11M/493M
------------------------------------------------------------------------

由於我們沒有運行過migration, 所以所有migration腳本都處於pending狀態,包括changelog table本身。當我們運行migrate up命令之後,腳本的狀態便會發生相應的改變。

Migrate up, down

爲了顯示更多up, down以及後續的version操作,再次新建一個數據表migrate new 'create table author'此時的author和blog應該都處於pending狀態。

minggong:migration-test minggong$ migrate status
------------------------------------------------------------------------
-- MyBatis Migrations - status
------------------------------------------------------------------------
ID             Applied At          Description
================================================================================
20140817132704    ...pending...    create changelog
20140817132705    ...pending...    first migration
20140817142201    ...pending...    create blog table
20140817154537    ...pending...    create table author

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 21:21:49 GMT+05:30 2014
-- Final Memory: 11M/493M
------------------------------------------------------------------------
minggong:migration-test minggong$ migrate up
------------------------------------------------------------------------
-- MyBatis Migrations - up
------------------------------------------------------------------------
========== Applying: 20140817132704_create_changelog.sql =======================
--  Create Changelog
-- Default DDL for changelog table that will keep
-- a record of the migrations that have been run.
-- You can modify this to suit your database before
-- running your first migration.
-- Be sure that ID and DESCRIPTION fields exist in
-- BigInteger and String compatible fields respectively.
CREATE TABLE CHANGELOG (
ID NUMERIC(20,0) NOT NULL,
APPLIED_AT VARCHAR(25) NOT NULL,
DESCRIPTION VARCHAR(255) NOT NULL
)

ALTER TABLE CHANGELOG
ADD CONSTRAINT PK_CHANGELOG
PRIMARY KEY (id)


========== Applying: 20140817132705_first_migration.sql ========================
--  First migration.
-- Migration SQL that makes the change goes here.

========== Applying: 20140817142201_create_blog_table.sql ======================
--  create blog table
-- Migration SQL that makes the change goes here.

========== Applying: 20140817154537_create_table_author.sql ====================
--  create table author
-- Migration SQL that makes the change goes here.

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 21:22:17 GMT+05:30 2014
-- Final Memory: 13M/493M
------------------------------------------------------------------------

migrate up命令會將所有的sql進行up,所有處於pending狀態的SQL腳本都會進行執行。對應的migrate down則是undo sql腳本的執行,也就是執行sql中用戶自定義的UNDO部分。不同的是migrate down只能回退一步,所以回退到初始狀態則需要運行多次的migrate down操作。當然也可以直接指定參數,本例中我們指定回退4步migrate down 4:
minggong:migration-test minggong$ migrate status
————————————————————————
– MyBatis Migrations - status
————————————————————————
ID Applied At Description
================================================================================
20140817132704 2014-08-17 21:22:17 create changelog
20140817132705 2014-08-17 21:22:17 first migration
20140817142201 2014-08-17 21:22:17 create blog table
20140817154537 2014-08-17 21:26:01 create table author

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 21:26:07 GMT+05:30 2014
-- Final Memory: 11M/493M
------------------------------------------------------------------------
minggong:migration-test minggong$ migrate down 4
------------------------------------------------------------------------
-- MyBatis Migrations - down
------------------------------------------------------------------------
========== Undoing: 20140817154537_create_table_author.sql =====================
-- @UNDO
-- SQL to undo the change goes here.

========== Undoing: 20140817142201_create_blog_table.sql =======================
-- @UNDO
-- SQL to undo the change goes here.

========== Undoing: 20140817132705_first_migration.sql =========================
-- @UNDO
-- SQL to undo the change goes here.

========== Undoing: 20140817132704_create_changelog.sql ========================
-- @UNDO
DROP TABLE CHANGELOG

Changelog doesn't exist. No further migrations will be undone (normal for the last migration).

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 21:29:53 GMT+05:30 2014
-- Final Memory: 14M/493M
------------------------------------------------------------------------
minggong:migration-test minggong$ migrate status
------------------------------------------------------------------------
-- MyBatis Migrations - status
------------------------------------------------------------------------
ID             Applied At          Description
================================================================================
20140817132704    ...pending...    create changelog
20140817132705    ...pending...    first migration
20140817142201    ...pending...    create blog table
20140817154537    ...pending...    create table author

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 21:30:09 GMT+05:30 2014
-- Final Memory: 11M/493M
------------------------------------------------------------------------

Migrate verison

回滾到指定的version狀態,後面需要加上version的ID: migrate verison 20140817132705

minggong:migration-test minggong$ migrate status
------------------------------------------------------------------------
-- MyBatis Migrations - status
------------------------------------------------------------------------
ID             Applied At          Description
================================================================================
20140817132704 2014-08-17 22:23:05 create changelog
20140817132705 2014-08-17 22:23:25 first migration
20140817142201 2014-08-17 22:23:25 create blog table
20140817154537 2014-08-17 22:23:25 create table author
20140817164341 2014-08-17 22:23:25 create table book

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 22:23:36 GMT+05:30 2014
-- Final Memory: 11M/493M
------------------------------------------------------------------------
minggong:migration-test minggong$ migrate version 20140817142201
------------------------------------------------------------------------
-- MyBatis Migrations - version
------------------------------------------------------------------------
Downgrading to: 20140817142201
========== Undoing: 20140817164341_create_table_book.sql =======================
-- @UNDO
-- SQL to undo the change goes here.

========== Undoing: 20140817154537_create_table_author.sql =====================
-- @UNDO
-- SQL to undo the change goes here.


------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 22:23:43 GMT+05:30 2014
-- Final Memory: 13M/493M
------------------------------------------------------------------------
minggong:migration-test minggong$ migrate status
------------------------------------------------------------------------
-- MyBatis Migrations - status
------------------------------------------------------------------------
ID             Applied At          Description
================================================================================
20140817132704 2014-08-17 22:23:05 create changelog
20140817132705 2014-08-17 22:23:25 first migration
20140817142201 2014-08-17 22:23:25 create blog table
20140817154537    ...pending...    create table author
20140817164341    ...pending...    create table book

------------------------------------------------------------------------
-- MyBatis Migrations SUCCESS
-- Total time: 0s
-- Finished at: Sun Aug 17 22:23:47 GMT+05:30 2014
-- Final Memory: 11M/493M
------------------------------------------------------------------------

Migrate pending

migrate up 命令只能向上upgrade,而在多人合作中如果migration sql腳本先創建但是後提交,同步到一臺服務器上就有可能出現中間某個文件處於pending狀態,這時使用migrate up是不能使其執行的。

這種情況如果這個sql基本和其他sql無依賴時,可以直接使用migrate up使處於pending狀態的腳本被執行。官方解釋這是不推薦的做法。另外一種做法是使用migrate version [ID]回到pending版本之前的狀態,然後再次執行migrate up,從而完成整個執行操作,這種做法是推薦的比較安全的。

Migrate script

使用方法爲migrate script <V1> <V2> > file.sql

migrate 20140817142201 20140817164341 > do.sql這個do腳本的執行將會應用上述兩個狀態的執行author和book。

migrate 20140817164341 20140817142201 > undo.sql 這個將undo腳本執行可以回滾V1和V2之間的即上述狀態。

如果要在首尾之間回滾,則可以用 0 代替原始版本ID

migrate 0 20140817164341 > do.sql

migrate 20140817164341 0 > undo.sql


但是對於上述的script腳本直接使用 migrate do.sql執行卻一直報錯!官方也沒有對單個的腳本執行有說明。後續弄清楚了再補充上來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章