设为首页 收藏本站
查看: 1583|回复: 0

[经验分享] 使用liquibase-maven-plugin实现持续数据库集成

[复制链接]

尚未签到

发表于 2016-11-22 05:26:02 | 显示全部楼层 |阅读模式
  数据库版本管理、持续集成一直都是大家比较关心的问题,网上也有很多相关的文章介绍。一直都很羡慕ruby on rails的database migration,非常强大,好在java阵营也有类似的工具可以帮助大家管理数据库版本,实现数据库迁移。本文将针对liquibase-maven-plugin这个maven插件做详细的介绍,希望能对大家有所帮助。
  一、配置properties-maven-plugin,使maven加载外部属性配置文件
  liquibase需要配置数据库的连接属性及驱动等参数,如果这些参数直接配置在pom文件中,会增加配置管理人员的工作量,因此希望能够统一读取web应用中已经配置好的properties文件中的配置属性,可以使用properties-maven-plugin插件导入配置文件,配置示例如下:



    <plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${basedir}/src/main/resources/conf/geoq.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
  geoq.properties配置示例如下:



    jdbc.driverClassName=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/geoq_dev
jdbc.username=postgres
jdbc.password=4652
  那么就可以在pom中使用${PropertyNmae}引用配置属性,如



    <configuration>
<changeLogFile>src/main/resources/liquiabse/business_table.xml</changeLogFile>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
</configuration>
  二、配置liquibase-maven-plugin
  配置示例如下:



    <plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>2.0.5</version>
<dependencies>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>2.0.5</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<changeLogFile>src/main/resources/liquiabse/business_table.xml</changeLogFile>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
</configuration>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
</plugin>
  1、需要通过dependency引入依赖jar包liquibase-core,版本号与插件版本号一致
  2、通过phase参数指定何时运行,一般为process-resources
  3、changeLogFile参数指定liquibase数据库变更日志文件
  4、driver、url、username、password配置数据库连接参数
  三、根据数据库生成数据库变更日志文件
  针对已有的数据库,如何产生对应的数据库变更日志文件,可以使用generateChangeLog指令,使用该指令需要下载liquibase的执行程序,命令示例如下:



    liquibase --driver=org.postgresql.Driver --classpath="C:\Program Files (x86)\PostgreSQL\pgJDBC\postgresql-9.1-901.jdbc4.jar" --changeLogFile=db.changelog.xml --url="jdbc:postgresql://localhost:5432/geoq_dev" --username=postgres --password=4652 generateChangeLog
  generateChangeLog默认只会创建数据库结构的变更日志文件,如果希望创建插入数据的变更日志文件,可以使用参数diffTypes,该参数包括如下可选项:


  • tables [DEFAULT]表


  • columns [DEFAULT]  列


  • views [DEFAULT]  视图


  • primaryKeys [DEFAULT]  主键


  • indexes [DEFAULT]  索引


  • foreignKeys [DEFAULT]  


  • sequences [DEFAULT]


  • data



    liquibase --driver=org.postgresql.Driver --classpath="C:\Program Files (x86)\PostgreSQL\pgJDBC\postgresql-9.1-901.jdbc4.jar" --changeLogFile=db.changelog.xml --url="jdbc:postgresql://localhost:5432/geoq_dev_full" --username=postgres --password=4652 --diffTypes=data generateChangeLog
  比较两个数据库:



    liquibase --driver=org.postgresql.Driver --classpath="C:\Program Files (x86)\PostgreSQL\pgJDBC\postgresql-9.1-901.jdbc4.jar" --changeLogFile=db.changelog.xml --url="jdbc:postgresql://localhost:5432/geoq_dev" --username=postgres --password=4652 diffChangeLog --referenceUrl="jdbc:postgresql://localhost:5432/geoq_dev_full" --referenceUsername=postgres --referencePassword=4652
  四、对现有数据库进行重构
  数据库变更日志文件可以对数据库的变更进行版本管理,并且可以摆脱对特定数据库的依赖,因此需要了解数据库变更日志文件的相关语法,下面分别介绍如何通过数据库变更日志配置数据库重构。
  1、编辑列:
  添加列



    <changeSet id="4" author="joe">
<addColumn tableName="distributor">
<column name="phonenumber" type="varchar(255)"/>
</addColumn>
</changeSet>
  添加自增列:



    <column autoIncrement="true" name="module_config_id" type="int" startWith="1">
<constraints nullable="false" primaryKey="true" primaryKeyName="pk_t_module_config"/>
</column>
  删除列:



    <dropColumn tableName="distributor" columnName="phonenumber"/>
  修改已存在的列为自增列



    <addAutoIncrement tableName="person" columnName="id" columnDataType="int"/>
  修改postgresql自增列当前索引值:liquibase不支持该操作,可以使用sql标签实现



    <sql>
ALTER SEQUENCE t_role_role_id_seq RESTART WITH 3;
</sql>
  2、创建表:



    <changeSet id="3" author="betsey">
<createTable tableName="distributor">
<column name="id" type="int">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(255)">
<constraints nullable="false"/>
</column>
<column name="address" type="varchar(255)">
<constraints nullable="true"/>
</column>
<column name="active" type="boolean" defaultValue="1"/>
</createTable>
</changeSet>
  3、操作数据:



    <changeSet id="3" author="betsey">
<code type="section" width="100%">
<insert tableName="distributor">
<column name="id" valueNumeric="3"/>
<column name="name" value="Manassas Beer Company"/>
</insert>
<insert tableName="distributor">
<column name="id" valueNumeric="4"/>
<column name="name" value="Harrisonburg Beer Distributors"/>
</insert>
</changeSet>
  应该编写用于操作数据的 SQL 脚本,因为使用 LiquiBase XML 变更集限制很多。有时候使用 SQL 脚本向数据库应用大量的变更会简单一些。LiquiBase 也可以支持这些情景。
  如下例为从 LiquiBase 变更集运行一个定制 SQL 文件



    <changeSet id="6" author="joe">
<sqlFile path="insert-distributor-data.sql"/>
</changeSet>
  编写changeset时,如果字段的内容为html标签,可以使用<![CDATA[html tag]]符号导入带有html标签的文本。
  4、操作序列:
  创建序列



<createSequence sequenceName="seq_employee_id"/>


  sequenceName

  序列名称 [required]

  schemaName

  表schema名称

  incrementBy

  自增间隔值

  minValue

  序列的最小值

  maxValue

  序列的最大值

  ordered

  'true' 或者 'false'

  startValue

  序列的起始值

  修改序列



<alterSequence sequenceName="seq_employee_id" incrementBy="10"/>


  sequenceName

  序列的名称 [required]

  incrementBy

  新的自增间隔值 [required]

  五、liquibase-maven-plugin基本命令


  • 更新数据库:mvn liquibase:update
  • 打版本标签:mvn liquibase:tag
  • 回滚到最近的更新版本,或指定的标签版本,或日期,或更新次数:mvn liquibase:rollback -Dliquibase.rollbackCount=1


  • 生成sql更新脚本:mvn liquibase:updateSQL

六、数据库版本控制
  1、添加版本标签:
  a、使用命令行:



mvn liquibase:tag -Dliquibase.tag=checkpoint
  b、使用配置文件:



    <executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tag>${project.version}</tag>
</configuration>
<goals>
<goal>update</goal>
<goal>tag</goal>
</goals>
</execution>
</executions>
  2、可以使用如下命令回滚到某个版本:



    mvn liquibase:rollback -Dliquibase.rollbackTag=checkpoint
  对应的maven配置为:



    <executions>
<execution>
<phase>process-resources</phase>
<configuration>
<changeLogFile>src/main/resources/liquiabse/master-changelog.xml</changeLogFile>
<driver>${jdbc.driverClassName}</driver>
<url>${jdbc.url}</url>
<username>${jdbc.username}</username>
<password>${jdbc.password}</password>
<rollbackTag>1.1</rollbackTag>
</configuration>
<goals>
<goal>update</goal>
<goal>rollback</goal>
</goals>
</execution>
</executions>
  rollback操作可选参数包括:



  changeLogFile

  String

  设置Liquibase变更集文件

  clearCheckSums

  boolean

  标识是否强制清除数据库表校验.
  默认值为:false.

  contexts

  String

  配置Liquibase执行的上下文,多个上下文可以使用逗号分隔

  databaseClass

  String

  数据库对象的类

  defaultSchemaName

  String

  数据库连接使用的默认数据库结构名称

  driver

  String

  数据库连接的驱动名称

  emptyPassword

  boolean

  已过期。是否使用空字符串或null作为数据库连接密码
  默认值为:false.

  expressionVariables

  Map

  传递给插件的数组变量

  expressionVars

  Properties

  传递给插件的数组变量

  includeArtifact

  boolean

  是否允许为获取Liquibase属性或数据库变更日志时包含maven项目组件
  默认值为:true.

  includeTestOutputDirectory

  boolean

  是否允许为获取Liquibase属性或数据库变更日志时包含测试输出目录
  默认值为:true.

  logging

  String

  控制插件输出的日志级别。 可选值包括:"all", "finest", "finer", "fine", "info", "warning", "severe" or "off",注意该值是区分大小写的。
  默认值为:INFO.

  password

  String

  数据库连接密码

  promptOnNonLocalDatabase

  boolean

  是否允许控制用户执行远程数据库
默认值为:true.

  propertyFile

  String

  Liquibase属性文件位置

  propertyFileWillOverride

  boolean

  标志是否允许使用Liquibase属性文件覆盖插件的配置
  默认值为:false.

  rollbackCount

  int

  回滚的变更集个数
  默认值为:-1.

  rollbackDate

  String

  设置回滚的日期。日期格式要符合插件执行theDateFormat.getDateInstance()操作设置的日期格式

  rollbackTag

  String

  要回滚到那个tag

  server

  String

  在settings.xml中的服务器id进行身份验证时使用

  skip

  boolean

  设置为“true”跳过运行liquibase,该参数不推荐使用

  systemProperties

  Properties

  传递到数据库的系统属性

  url

  String

  数据库连接地址

  username

  String

  用户名称

  verbose

  boolean

  控制调用插件的输出的详细程度。
  默认值为:false.

  
也可以指定回滚的步数(changeset个数):



    mvn liquibase:rollback -Dliquibase.rollbackCount=3
  或者生成回滚的sql脚本:



    mvn liquibase:rollbackSQL -Dliquibase.rollbackTag=checkpoint
  3、可以根据不同的版本分别创建相关changelog文件,使用include标签分别引入,如主干changelog文件为master-changelog.xml,定义如下:



    <?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
<include file="src/main/resources/liquibase/liquibase-create-tables.xml" />
<include file="src/main/resources/liquibase/liquibase-insert-data.xml" />
<include file="src/main/resources/liquibase/liquibase-mobile-menu.xml" />
…...
<include file="src/main/resources/liquibase/liquibase-update-to-1.4.xml"/>
<include file="src/main/resources/liquibase/liquibase-update-to-1.6.xml"/>
…...
</databaseChangeLog>
  七、创建特殊的类型的字段
  在changelog文件中,如希望创建postgresql支持的enum,可以使用的方法如下:
  1、使用sql脚本直接创建



    <changeSet id="1" author="Arthur">
<sql>CREATE TYPE my_state AS ENUM ('yes','no')</sql>
<table name="foo">
<column name="state" type="my_state"/>
</table>
</changeSet>
  2、使用约束



    <changeSet id="1" author="X">
<table name="t">
<column name="c" type="varchar(3)"/>
</table>
<sql>ALTER TABLE t ADD CONSTRAINT check_yes_no CHECK (c = 'yes' OR c = 'no')</sql>
</changeSet>
  3、获取系统当前时间
  首先定义不同数据库获取时间的属性标签



    <property name="now" value="sysdate" dbms="oracle"/>
<property name="now" value="now()" dbms="mysql"/>
  在changesets中引用该属性



    <column name="Join_date" defaultValueFunction="${now}"/>
  完整示例如下:



    <property name="now" value="UNIX_TIMESTAMP()" dbms="mysql"/>
<changeSet id="emp_1" author="Me">
<insert tableName="Emp" schemaName="XYZ">
<column name="EmpName" value="abc"/>
<column name="Join_date" valueDate="${now}"/>
<column name="Profile_last_update" valueDate="${now}"/>
<column name="group_name" value="BlahBlah"/>
</insert>
</changeset>
  八、支持多数据库
  可以在pom文件使用多个execution标签支持多数据库,但是需要注意每个execution一定要定义id标签



    <plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-plugin</artifactId>
<version>1.9.5.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<changeLogFile>src/main/resources/db.changelog.xml</changeLogFile>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost:3306/charm</url>  
<username>***</username>
<password>***</password>
</configuration>
<goals>
<goal>update</goal>
</goals>
</execution>
<execution>
<phase>process-resources</phase>
<configuration>
<changeLogFile>src/main/resources/db.changelog.xml</changeLogFile>
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost:3306/charm2</url>  
<username>***</username>
<password>***</password>
</configuration>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
</plugin>
  九、参考网站
  主站:http://www.liquibase.org/
  帮助手册:http://www.liquibase.org/manual/home
  properties-maven-plugin手册:http://www.liquibase.org/manual/maven

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-303587-1-1.html 上篇帖子: Portal for ArcGIS上传shp文件中文乱码可能情况 下篇帖子: [原创]Postgres-XC集群笔记-概念与环境搭建
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表