引言
Liquibase是一个数据库版本控制系统,它主要涉及数据库的结构,并在较小程度上涉及数据库的内容。 而且,数据库的描述一方面是相当抽象的,并且允许在较低级别使用各种DBMS,另一方面,您始终可以切换到特定DBMS的SQL方言,这非常灵活。 Liquibase是一个已建立的开源项目,并且在其本机Java环境之外积极使用,并且不需要Java的深入知识即可工作。 过去一直使用XML格式描述基本结构和基本更改,但现在同时支持YAML和JSON。
在本文中,我们将简要总结前几代的经验,并将重点介绍使用Maven与Liquibase一起工作。 我们将使用Ubuntu作为测试操作系统。
有关Liquibase的其他文章
环境设定
有多种启动Liquibase的方法,但是,使用Maven或Gradle最方便。
sudo apt install maven mvn -version
这里pom.xml充当Makefile-它已经包含所有必需的依赖项,设置和配置文件。
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test.db</groupId> <artifactId>db</artifactId> <version>1.0.0</version> <name>db</name> <description>Test Database</description> <packaging>pom</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <slf4j.version>1.7.24</slf4j.version> <logback.version>1.2.3</logback.version> <liquibase.version>3.6.2</liquibase.version> <postgresql.version>42.2.5</postgresql.version> <snakeyaml.version>1.23</snakeyaml.version> </properties> <dependencies> <!--Logging--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <!--JDBC drivers--> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>${postgresql.version}</version> </dependency> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>${liquibase.version}</version> </dependency> <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>${snakeyaml.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>${liquibase.version}</version> <configuration> <propertyFile>${profile.propertyFile}</propertyFile> <changeLogFile>${profile.changeLogFile}</changeLogFile> <dataDir>${profile.dataDir}</dataDir> <!-- log --> <verbose>${profile.verbose}</verbose> <logging>${profile.logging}</logging> <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase> </configuration> </plugin> </plugins> </build> <profiles> <!-- Development settings, -Denv=dev --> <profile> <id>dev</id> <activation> <property> <name>env</name> <value>dev</value> </property> </activation> <properties> <profile.propertyFile>dev/liquibase.properties</profile.propertyFile> <profile.changeLogFile>dev/master.xml</profile.changeLogFile> <profile.dataDir>dev/data</profile.dataDir> <profile.verbose>true</profile.verbose> <profile.logging>debug</profile.logging> </properties> </profile> <!-- Production settings, -Denv=prod --> <profile> <id>prod</id> <activation> <property> <name>env</name> <value>prod</value> </property> </activation> <properties> <profile.propertyFile>prod/liquibase.properties</profile.propertyFile> <profile.changeLogFile>prod/master.xml</profile.changeLogFile> <profile.dataDir>prod/data</profile.dataDir> <profile.verbose>false</profile.verbose> <profile.logging>info</profile.logging> </properties> </profile> </profiles> </project>
我们启动更新
完成pom.xml之后,我们可以开始更新数据库-liquibase:update命令。
为此,我们需要:
- liquibase.properties文件,具有用于连接数据库的设置(用户名/密码以及可能的其他参数)
- 具有基本更改的xml文件
- sh数据库更新启动脚本
数据库连接设置文件
liquibase.properties
username=test password=test referenceUsername=test # #url=jdbc:postgresql://dev/test #referenceUrl=jdbc:postgresql://dev/test_reference
基本变更文件
liquibase的主要概念是所谓的基本更改(changeset)。 它们可以包括结构更改和数据更改。 Liquibase使用databasechangelog和databasechangeloglock表来监视应用的更改。
<?xml version="1.1" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd"> <changeSet context="legacy" author="author (generated)" id="1"> <createTable tableName="test"> <column autoIncrement="true" name="id" type="SERIAL"> <constraints nullable="false"/> </column> <column name="user_name" type="VARCHAR(255)"/> <column name="preferences" type="TEXT"/> </createTable> </changeSet> </databaseChangeLog>
数据库更新启动脚本
这里liquibase:update是为dev配置文件和来自liquibase.url的基础执行的,liquibase.url以标准JDBC格式指定。 更新后,changeSet中指示的表和两个服务表databasechangelog和databasechangeloglock出现在database中 。
#!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified"
SQL生成而不更新数据库
有时,在开始更改之前,您需要查看所生成请求的内容。 liquibase:updateSQL和liquibase:rollbackSQL命令用于此目的。
#!/usr/bin/env bash mvn liquibase:updateSQL\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified" > /tmp/script.sql
有关changeSet的更多信息
更改可以采用不同的格式,包括常规sql或单独的文件。
每个更改可能包括一个回滚部分,允许您使用liquibase:rollback命令来回滚更改。 另外,您可以使用tagDatabase标记更改,例如,更方便地回滚到那里。
<changeSet context="legacy" author="author (generated)" id="1"> <createTable tableName="test"> <column autoIncrement="true" name="id" type="SERIAL"> <constraints primaryKey="true" primaryKeyName="test_pkey"/> </column> <column name="c1" type="VARCHAR(255)"/> <column name="c2" type="INTEGER"/> <column name="c3" type="SMALLINT"/> <column name="c4" type="VARCHAR(255)"/> <column name="c5" type="TEXT"/> <column name="c6" type="VARCHAR(255)"/> </createTable> </changeSet>
嵌入式SQL
<changeSet context="legacy" author="author" id="1-domain-some-domain"> <sql> CREATE DOMAIN public.some_domain AS bigint; ALTER DOMAIN public.some_domain OWNER TO test; </sql> <rollback> DROP DOMAIN public.some_domain; </rollback> </changeSet>
SQL文件
<changeSet context="legacy" author="author" id="1-user"> <sqlFile dbms="postgresql" path="sql/some.sql" relativeToChangelogFile="true" /> <rollback> delete from "some"; </rollback> </changeSet>
标签
<changeSet context="legacy" author="author" id="1-initial-changeset"> <tagDatabase tag="initial"/> </changeSet>
启动上下文
为了更方便地管理各种配置(例如,开发/生产),可以使用上下文。 上下文是在上下文的changeSet属性中指定的,然后由Maven使用-Dcontexts参数启动。
随环境变化
<changeSet context="legacy" author="author" id="1-initial-changeset"> <tagDatabase tag="initial"/> </changeSet>
触发上下文更改
#!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified"\ -Dliquibase.contexts=non-legacy
回滚更改
该操作与更新相反,在大多数情况下,它是自动支持的。 对于其他用户,可以通过回滚部分完成该任务。 它由liquibase:rollback命令启动。
回滚更改
<changeSet context="legacy" author="author" id="1-domain-some-domain"> <sql> CREATE DOMAIN public.some_domain AS bigint; ALTER DOMAIN public.some_domain OWNER TO test; </sql> <rollback> DROP DOMAIN public.some_domain; </rollback> </changeSet>
启动回滚
#!/usr/bin/env bash mvn liquibase:update\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test?prepareThreshold=0&stringtype=unspecified"\ -Dliquibase.contexts=non-legacy
比较方式
在开发中,可以方便地将两个现有数据库进行比较以进行更改。 在设置(或启动参数)中,您需要添加到参考数据库的链接以及用于访问它的数据。
liquibase.properties
referenceUsername=test referenceUrl=jdbc:postgresql://dev/test_reference
电路比较
比较url和referenceUrl方案。
#!/usr/bin/env bash mvn liquibase:diff\ -Denv=dev\ -Dliquibase.referenceUrl="jdbc:postgresql://dev/test?prepareThreshold=0"\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.diffChangeLogFile=dev/diff.xml
保存架构
保存当前数据库模式(带或不带数据)也很有用。 必须记住,Liquibase保存的方案与原始方案不完全对应,例如,使用的域或继承将需要单独添加(请参阅限制)。
保存架构而不考虑数据
保存现有数据库的架构。
#!/usr/bin/env bash mvn liquibase:generateChangeLog\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.outputChangeLogFile=dev/changelog.xml
用数据保存模式
用数据保存现有数据库的架构。
#!/usr/bin/env bash mvn liquibase:generateChangeLog\ -Denv=dev\ -Dliquibase.url="jdbc:postgresql://dev/test_reference?prepareThreshold=0"\ -Dliquibase.outputChangeLogFile=dev/changelog.xml
局限性和问题
处理数据库中的二进制数据
上载,比较和使用二进制数据存在某些问题,特别是生成更改的问题。
继承和通用列
源代码
替代解决方案
飞路
与Liquibase一起在Java社区中很流行-http://flywaydb.org/documentation
斯奇奇
相当于Perl- http://sqitch.org
流浪汉
.Net的模拟-https: //github.com/schambers/fluentmigrator
达比尼
Ruby的类比-http: //dbgeni.appsintheopen.com/manual.html
应用领域
项目结构
pom.xml - maven makefile dev liquibase.properties - login/password etc master.xml - changesets
如何将liquibase添加到现有项目
基础更改如何工作
有关更新的更多信息
更多关于变化的产生
有关自定义SQL的更多信息
处理特定于数据库的数据类型
<createTable tableName="t_name"> ... <column name="doubleArray" type="DOUBLE_ARRAY"/> ... </createTable> <modifySql dbms="postgresql"> <replace replace="DOUBLE_ARRAY" with="double precision[][]"/> </modifySql>
其他