目录
1 引入
Dbmaintain是mvn的插件,所以可以通过mvn来理解,mvn就是提供了命名规范和mvn命令。所以dbmaintain这个插件也是通过命名规范和mvn命令来实现的。
2 解析
2.1 三种脚本
2.1.1 incremental脚本
1. increament的脚本特点
不支持修改文件内容,只能执行一次。
2. 脚本命名格式
1 |
数字_xxx.sql |
3. 存放位置
对于一个incremental scripts,(命名为”数字_xx.sql”),不仅可以放置到名字格式为”数字_xx”目录下面,而且还可以放到名字格式为”非数字_xx”的目录下面
4 . dbmaintain中设置version的作用
假设在dbmaintain.properties中设置的version =2 ,那么对于如下目录,执行”mvn dbmaintain:updateDatabase”时,对于01_2013xx/01_xx.sql没有被执行。
所以,version的作用是:
(1)只针对”数字_xx”目录,此时只执行数字大于version目录下的increment脚本。
(2)“数字_xx”格式的目录下面只能存放increment脚本。
2.1.2 repeatable脚本
1. repeatalbe脚本特点
可以执行多次:如果发现脚本的md5的值发生变化,就重新执行这个脚本。
2. 脚本命名格式
1 |
非数字_xx.sql |
3. 存放位置
repeatable脚本只能存放在”非数字_xx”目录下面,不能存在“数字_xx”目录下面,否则就会报错。如下图,在数字开头的02_203xx的目录下面添加了一个repeable 脚本
此时运行”mvn dbmaintain:updateDatabase”出现如下错误
updateDatabase failed: Error in script 02_203xx/S1_xx.sql: Repeatable scripts cannot be located inside an indexed folder. -> [Help 1]
2.1.3 postprocessing目录
1. postprocessing脚本特点
一个脚本,被修改,那么prostprocessing目录下的所有脚本都会被执行。
1 2 |
与increment脚本和repeateable脚步的区别就在于: 这种脚本不是通过命名格式来表征的,而是通过指定一个postprocessing目录,放在这个目录下的脚步就是postprocessing脚步 |
2. 命名规范
(1)存放目录目录名字必须是postprocessing
(2)脚本命名需要index,如下文件夹格式
1 2 3 |
postprocessing ----01_compile_all.sql ----02_grant_select_to_read_user.sql |
3. 存放位置
为了能够在执行更新mvn dbmaintain:updateDatabase操作时识别出脚本为postprocessing脚本,需要在pom.xml中指明脚本路径和指明脚本是postprocessing脚本
1 2 3 4 5 |
<!--用于指明在执行updateDatabase命令时,哪些脚本要执行--> <scriptLocations>postprocessing</scriptLocations> <!-- 用于指明执行updateDatabase命令时,哪些脚本是postprocessing类型的脚本 --> <postProcessingScriptDirectoryName>postprocessing</postProcessingScriptDirectoryName> |
2.1.4 如何区分三种脚本
通过postprocessing脚本中一个问题来引入。如果此时再postprocessing下面建立了一个文件夹test,如下,那么此时的01_user.sql脚本是否还是postprocessing脚本?
1 2 3 |
postprocessing - test - 01_user.sql |
1. 答案:不是了。
我们进行如下测试:首先成功执行01_user_sql.sql,然后修改01_user.sql再执行,就会报错了。如下错误:
Failed to execute goal org.dbmaintain:dbmaintain-maven-plugin:2.4:updateDatabase (default-cli) on project dbmaintain: Execution default-cli of goal org.dbmaintain:dbmaintain-maven-plugin:2.4:updateDatabase failed: Following irregular script updates were detected:
2. 此时上述的01_user.sql被当成那种类型的脚本了?
对于判断脚本是increament scriptes还是repeatable scriptes两种类型中哪一种?
(1)如果是以 ” 数字_xxx.sql”格式命名脚本,此时就是incremental scriptes。即使包含这个脚本的目录不是”版本号_XX“的格式,此时脚本也是incremental scriptes。至于命名目录为”版本号_XX”的格式是为了使用dbmaintain的dmmaintain.properties提供的版本的功能。
(2)如果是以 “非数字_xx.sql”格式命名脚本,此时就是repeatetable scriptes;
(3) 对于判断脚本是increament scriptes还是repeatable scriptes两种类型中哪一种时,只需要看的是脚本命名格式。
通过上述,可以知道一个increment scriptes,不仅可以放到”数字_xx”目录下面,而且还可以放到不是数字开头(“非数字_xx”)的目录下面。但是对于一个repeataple脚本是无法放到一个数字开头的目录(格式为:”数字_xxx”)下面的。如下图,在数字开头的02_203xx的目录下面添加了一个repeable 脚本,
(4)如何知道是postProcessing脚本呢?
需要在xml中 <postProcessingScriptDirectoryName>节点来指定。只有脚本的直接父目录是这个脚本才可以是postProcessing脚本。如下,
只有s1_xx.sql才是postProcessing脚本。
2.2 四种命令
1. mvn dbmaintain:updateDatabase
这种操作针对所有类型脚本,包括increatemental脚本、repeatetable脚本、postprocessing脚本。
2. mvn dbmaintain:markErrorScriptReverted
将在dbmaintain_scripts表中执行错误的记录删除掉
3. mvn dbmaintain:markErrorScriptPerformed
将在dbmaintain_scripts表中执行错误的记录的success字段修改为1
4. mvn dbmaintain:markDatabaseAsUpToDate
这个命令执行过程如下:
首先,删除 dbmaintain_scripts表中被删除脚本的记录;
然后,将存在脚本加入到dbmaintain_scripts,然后标记为正确,但是不执行sql脚本中操作
3 实践
3.1 项目规划化设计
3.1.1 目录规范化
采用父子模块,每一个模块表示一个数据库。包括doctor-scripts、mobile-scripts和statistic-scripts三个子模块,分别用于保存对于doctor库、mobile库和statistic
3.1.2 脚本命名规范
大家添加sql脚本时都需要重新拉一个新的分支。我们这里只是用过repeatable类型的脚本,添加了一repeatable脚本,还需要在rollback目录下面添加相应的回滚脚本。
在repeatable目录下添加一个脚本时需要考虑目录命名和脚本命令两部分,如下:
1.目录命名
子目录文件命名规范,分为含有JIRA和没有JIRA的bugfix两种来源:
(1)来源1:含有JIRA的类型
格式为
1 |
JyyyyMMdd_JiraId_需求名称 |
示例为
1 |
J20150303_123_test,其中20150303是日期,123是JiraId |
(2)来源2: 没有JIRA的bugFix的类型
格式,以大写字母F开头
1 |
FyyyyMMdd_需求名称 |
示例
1 |
F20150303_test,其中20150303是日期 |
2. 脚本命名
(1)格式
每一个脚本都需要一个index,且必须放置在后面
1 |
S索引号_脚本名字.sql |
(2)示例
1 |
S01_alter_city.sql |
3.2 pom.xml配置
在配置dbmaintain时,如何使用profile来区分不同数据库配置?
我们采用的父子工程,每一个数据库时一个子模块,我们在父pom.xml中定义了maven插件配置,这样子模块可以共享此配置,如下:
<
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
<build> <plugins> <plugin> <groupId>org.dbmaintain</groupId> <artifactId>dbmaintain-maven-plugin</artifactId> <version>2.4</version> <configuration> <scriptLocations>repeatable</scriptLocations> <scriptFileExtensions>sql</scriptFileExtensions> <autoCreateDbMaintainScriptsTable>true</autoCreateDbMaintainScriptsTable> <scriptEncoding>UTF-8</scriptEncoding> <configFile>dbmaintain.properties</configFile> <allowOutOfSequenceExecutionOfPatches>true</allowOutOfSequenceExecutionOfPatches> <databases> <database> <driverClassName>com.mysql.jdbc.Driver</driverClassName> <userName>${db.userName}</userName> <password>${db.password}</password> <url>${db.url}</url> <schemaNames>${db.schemaName}</schemaNames> </database> </databases> </configuration> <executions> <execution> <phase>install</phase> <goals> <goal>updateDatabase</goal> </goals> </execution> </executions> <dependencies> <dependency> <artifactId>mysql-connector-java</artifactId> <groupId>mysql</groupId> <version>5.1.21</version> </dependency> </dependencies> </plugin> </plugins> </build> |
在每一个子模块的pom.xml的<profiles>中配置各个测试环境的数据库连接,以dev环境为例
1 2 3 4 5 6 7 8 9 10 11 12 |
<profiles> <profile> <id>dev</id> <properties> <deploy.type>dev</deploy.type> <db.userName>用户名</db.userName> <db.password>密码</db.password> <db.url>数据库连接</db.url> <db.schemaName>crm_doctor</db.schemaName> </properties> </profile> </profiles> |
(全文完)