1 概述当今的大多数软件开发团队已经掌握了使用SVN等SCM工具对源代码和文档进行有效的版本控制, 但是,如何将DB的变更也纳入到版本控制中却是一个亟待解决的难题; 这个问题普遍存在却被严重忽视,常见的最“正规”的做法就是在工程的DB目录下随意堆放sql脚本,在需要的时候从里面挑选出要执行的脚本或脚本片段拿去执行; 这种做法非常的繁琐而容易出错,严重拖累了软件开发团队前进的脚步。 2 MyBatis Schema Migrations介绍The MyBatis Schema Migrations tool(http://code.google.com/p/mybatis/wiki/Migration 下文简称Migrations)是一个开源的用于DB版本控制的命令行工具, Migrations通过生成统一格式的DDL脚本模板、在目标DB中记录版本信息和当前状态,使得多人开发团队可以在多个DB环境上井然有序的工作,为敏捷和迭代开发提供强有力的技术保障。 同时Migrations学习和使用又非常简单,常用的命令不到10个; 3 DB的版本控制流程3.1 安装Migrations命令行工具首先要为每个项目成员安装Migrations,安装过程很简单:
3.2 初始化Migrations工作目录接下来需要在你的工程下为Migrations创建一个工作目录(如D:\zk-env\workspace\KTF-UAAS\db); 键入下列命令来初始化工作目录:
然后会发现工作目录下增加了drivers、environments、scripts目录,它们分别用来存放DB驱动、各个环境DB连接参数和DB变更脚本; 3.2.1 配置数据库驱动将项目实际使用的数据库驱动jar拷贝到drivers目录下; 3.2.2 配置数据库连接打开environments目录,编辑development.properties为Migrations指定开发环境DB的连接参数,修改时区为time_zone=GMT+8:00(假设您的团队在中国大陆); 参照development.properties创建uat.properties、sit.properties等用于指定uat环境和集成测试环境DB连接参数; 3.2.3 记录数据库基线scripts目录中的bootstrap.sql用于记录数据库的最原始的状态——基线,即你在使用Migrations工具之前的数据库Scheme; 3.2.4 提交Migrations工作目录到SVN为了在整个团队统一Migrations配置,完成上述配置后需将工作目录提交SVN,然后其他人update即可; 另外,接下来每个开发人员在自己本地创建的DB变更脚本也会放在scripts目录下通过SVN进行版本控制; 接下来,项目组成员就可以各自在本地使用Migrations创建数据库变更了; 3.3 创建数据库变更键入下列命令创建一个数据库变更:新建表TAbc
然后scripts目录下会增加一个文件——20130709155240_liyq_add_table_tabc.sql,内容如下:
根据注释不难猜到这是一个模板,分上下两部分:上半部分(也就是–//@UNDO前)是要对数据库做的变更操作脚本,下半部分是与之对应的回退脚本; 这里涉及到一个技巧:
3.4 在不同环境执行DB变更接下来就可以通过Migrations执行上述脚本来改变目标DB,并验证脚本正确性了; 3.4.1 查看目标DB状态执行前先看看DB的当前状态——哪些脚本已经执行过了,哪些还没执行 例如下图表明:当前DB处于版本20130620154141,本地的20130709163435变更还未执行;详见MyBatis Migrations – MyBatis Migrations | Migrate > status 3.4.2 前进执行“migrate up”命令,Migrations会在目标DB执行所有还未执行的脚本(这里只有20130709163435) 然后再次查看DB状态,发现20130709163435已执行! 此时你还会发现目标DB中增加了一个ChangeLog表,没错,Migrations正是通过这个表来记录DB状态的; 3.4.3 后退执行“migrate down”命令,Migrations会在目标DB“后退一步”——执行当前版本对应的回退脚本,使目标DB回退到上一个版本(20130620154141)的状态,如下图: 3.4.4 在其它DB环境前进和后退上面的三个命令(status、up、down)都可以增加一个env参数,用来告诉Migrations在哪个DB执行该命令, 例如migrate status --env=uat用来查看uat.properties中指向的那个目标DB的当前状态; 没有指定env参数时,默认为development; 通过这个简单的参数,团队可以轻松的管理多个DB环境状态,任意切换、前进和后退,而脚本只有一套。 至此,我们完成了一个DB变更的开发和测试,并且在多个DB实例中执行了这一变更。 3.5 脚本文件的共享与同步虽然你已经通过执行上述DB变更改变了DB状态,但团队中的其他成员的工作目录中还没有这个变更脚本, 这似乎是有问题的,至少其它人无法回退这一变更,在你回退后其他人也无法前进到该变更所在的DB版本! 出现这个问题是因为Migrations在目标DB中记录该DB的变更(通过那个ChangeLog表),而对于团队如何分发和同步变更脚本却无法控制, 因此我们需要借助SVN来在团队中共享和同步脚本,这没什么特别的,跟所在工程下的其它目录和文件一样进行SVN操作即可; 不过好在即使是脚本没有同步的情况下执行Migrations命令也不太可能造成冲突,因为Migrations生成的脚本文件是带时间戳的,精确到秒,除非多个人在同一秒内建了同名的变更才可能冲突。 3.6 导出DB变更脚本3.6.1 系统发布的重要环节——DB发布随着开发工作的推进项目中的DB变更越来越多。 如果你是这个项目的开发经理,某一天你决定要做一次生成发布,把团队过去一个月的工作成果发布到生产环境供客户使用, 此时,你除了要为应用构建最新版本的war包以外,还要准备一个DB变更脚本用来在生产DB执行,因为过去的一个月中你的团队除了修改了大量代码,还对开发测试环境的DB做了大量变更, 这些变更必须准确无误的在生产DB中也执行一遍,否则新版本的应用将无法工作。 于是你对工程进行SVN更新,进入db/scripts目录,映入你眼帘的是清晰整齐的脚本文件, 轻轻键入一个命令(migrate status --env=xxx)就能清楚的知道各个DB环境的状态; 3.6.2 生成DB变更脚本你可能会打算直接在DB目录中找出需要发布的脚本文件拿到生产环境去执行,但这样做就跟没有使用Migrations的团队没什么区别了; Migrations的script命令就是用来做这件事的,执行下列命令,你会得到想要的东西: 如果将上面命令中的两个版本号对调位置,得到的就是本次系统发布的DB回退脚本, 一旦你在生产DB执行了数据库变更后又不想发布应用了(比如突然发现这个应用版本存在严重缺陷), 那么这个回退脚本就派上用场了——它能帮你把生产DB恢复到之前的状态——能够使前一版本应用正常工作的状态,而不至于使你陷入进退两难! |
|