对现有数据库应用重构 & 常见的数据库操作
随着新特性添加到了应用程序中,经常需要变更数据库的结构或修改表约束。LiquiBase 提了超过 30 种数据库重构支持(参见 参考资料)。本节将介绍 4 种重构:添加列(Add Column)、删除列(Drop Column)、创建表(Create Table)和操作数据。
添加列
在项目的开始,几乎不可能考虑到数据库中的所有列。而有时候,用户要求新的特性 —例如为存储在系统中的信息收集更多的数据 —这就要求添加新的列。清单 4 使用 LiquiBase addColumn重构,向数据库中的 distributor表添加了一个列:
清单 4. 使用 LiquiBase 变更集中的 Add Column 数据库重构
<changeSet id="4" author="joe">
<addColumn tableName="distributor">
<column name="phonenumber" type="varchar(255)"/>
</addColumn>
</changeSet>
删除列
假如在以后几个版本中,您想要删除在清单 4 添加的 phonenumber列。只需要调用 dropColumn重构,如清单 5 所示:
删除一个数据库列
<dropColumn tableName="distributor" columnName="phonenumber"/>
创建表
向数据库添加一个新表也是常见的数据库重构。清单 6 创建了一个新表 distributor,定义了列、约束和默认值:
清单 6. 在 LiquiBase 中创建一个新数据库表
<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>
操作数据
在应用了结构性数据重构后(例如添加列和创建表),通常需要向受重构影响的表中插入数据。此外,可能需要修改查找表(或其他类型的表)中的现有数据。清单 7 展示了如何使用一个 LiquiBase 变更集插入数据:
清单 7. 使用一个 LiquiBase 变更集插入数据
<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 也可以支持这些情景。清单 8 调用变更集中的 insert-distributor-data.sql来插入 distributor表数据:
清单 8. 从 LiquiBase 变更集运行一个定制 SQL 文件
<changeSet id="6" author="joe">
<sqlFile path="insert-distributor-data.sql"/>
</changeSet>
changeset xsd 参考
<!-- Children for changeSet -->
<xsd:group name="changeSetChildren">
<xsd:choice>
<xsd:element ref="comment" maxOccurs="1" />
<xsd:element ref="createTable" maxOccurs="unbounded" />
<xsd:element ref="dropTable" maxOccurs="unbounded" />
<xsd:element ref="createView" maxOccurs="unbounded" />
<xsd:element ref="renameView" maxOccurs="unbounded" />
<xsd:element ref="dropView" maxOccurs="unbounded" />
<xsd:element ref="insert" maxOccurs="unbounded" />
<xsd:element ref="addColumn" maxOccurs="unbounded" />
<xsd:element ref="sql" maxOccurs="unbounded" />
<xsd:element ref="createProcedure" maxOccurs="unbounded" />
<xsd:element ref="dropProcedure" maxOccurs="unbounded" />
<xsd:element ref="sqlFile" maxOccurs="unbounded" />
<xsd:element ref="renameTable" maxOccurs="unbounded" />
<xsd:element ref="renameColumn" maxOccurs="unbounded" />
<xsd:element ref="dropColumn" maxOccurs="unbounded" />
<xsd:element ref="mergeColumns" maxOccurs="unbounded" />
<xsd:element ref="modifyDataType" maxOccurs="unbounded" />
<xsd:element ref="createSequence" maxOccurs="unbounded" />
<xsd:element ref="alterSequence" maxOccurs="unbounded" />
<xsd:element ref="dropSequence" maxOccurs="unbounded" />
<xsd:element ref="renameSequence" maxOccurs="unbounded" />
<xsd:element ref="createIndex" maxOccurs="unbounded" />
<xsd:element ref="dropIndex" maxOccurs="unbounded" />
<xsd:element ref="addNotNullConstraint" maxOccurs="unbounded" />
<xsd:element ref="dropNotNullConstraint" maxOccurs="unbounded" />
<xsd:element ref="addForeignKeyConstraint" maxOccurs="unbounded" />
<xsd:element ref="dropForeignKeyConstraint" maxOccurs="unbounded" />
<xsd:element ref="dropAllForeignKeyConstraints"
maxOccurs="unbounded" />
<xsd:element ref="addPrimaryKey" maxOccurs="unbounded" />
<xsd:element ref="dropPrimaryKey" maxOccurs="unbounded" />
<xsd:element ref="addLookupTable" maxOccurs="unbounded" />
<xsd:element ref="addAutoIncrement" maxOccurs="unbounded" />
<xsd:element ref="addDefaultValue" maxOccurs="unbounded" />
<xsd:element ref="dropDefaultValue" maxOccurs="unbounded" />
<xsd:element ref="addUniqueConstraint" maxOccurs="unbounded" />
<xsd:element ref="dropUniqueConstraint" maxOccurs="unbounded" />
<xsd:element ref="setTableRemarks" maxOccurs="unbounded" />
<xsd:element ref="setColumnRemarks" maxOccurs="unbounded" />
<xsd:element ref="customChange" maxOccurs="unbounded" />
<xsd:element ref="update" maxOccurs="unbounded" />
<xsd:element ref="delete" maxOccurs="unbounded" />
<xsd:element ref="loadData" maxOccurs="unbounded" />
<xsd:element ref="loadUpdateData" maxOccurs="unbounded" />
<xsd:element ref="executeCommand" maxOccurs="unbounded" />
<xsd:element ref="stop" maxOccurs="unbounded" />
<xsd:element ref="output" maxOccurs="unbounded" />
<xsd:element ref="empty" maxOccurs="unbounded" />
<xsd:element ref="rollback" maxOccurs="1" />
<xsd:any namespace="##other" processContents="lax" minOccurs="0"
maxOccurs="unbounded" />
</xsd:choice>
</xsd:group>
liquibase 命令附录
命令名称 | 命令描述 |
---|---|
update | 更新数据库到当前版本 |
updateSQL | 写入SQL将数据库更新到currentversion或STDOUT |
updateCount <num> | 将下一个NUM更改应用到数据库 |
updateCountSQL <num> | 写入SQL以将下一个NUM更改应用到数据库 |
updateToTag <tag> | 使用指定的标记将数据库更新到变更集 |
updateToTagSQL <tag> | 使用指定的标记将SQL写入(到标准输出)到更改集 |
rollback <tag> | 将数据库回滚到指定标签的状态is was |
rollbackSQL <tag> | 生成数据库回滚到指定标签的sql |
rollbackToDate <date/time> | 将数据库回滚到给定日期/时间的状态is was。日期格式:yyyy-MM-dd 'HH: mm: ss |
rollbackToDateSQL <date/time> | 写入SQL以将数据库回滚到给定日期/时间版本的状态到STDOUT |
rollbackCount <value> | 回滚应用于数据库的最后一个<值>更改集 |
rollbackCountSQL <value> | 写入SQL以回滚最后一个<值>更改集到应用于数据库的stdoutapply |
futureRollbackSQL | 写入SQL,以便在更改日志中的更改完成后将数据库回滚到当前状态 |
futureRollbackSQL <value> | 在更改日志中的<值>更改完成后,写入SQL以将数据库回滚到当前状态 |
futureRollbackFromTagSQL <tag> | 写入(到标准输出)SQL,以便在更改后将数据库回滚到其当前状态 |
updateTestingRollback | 更新数据库,然后再次回滚更改。用于测试回滚支持 |
generateChangeLog | 写入更改日志XML以将数据库的当前状态复制到标准输出 |
snapshot | 将数据库的当前状态写入标准输出 |
snapshotReference | 将referenceUrl数据库的当前状态写入标准输出 |
Diff Commands | 数据库对比命令 |
diff [diff parameters] | 数据库对比命令 |
diffChangeLog [diff parameters] | 数据库对比日志 |
Documentation Commands | 文档命令 |
dbDoc <outputDirectory> | 基于当前数据库和更改日志生成类似javadoc的文档 |
Maintenance Commands | 维护命令 |
tag <tag string> | 给当前的数据库打标签,方便日后回滚 |
tagExists <tag string> | 检查对应的标签是否存在 |
status [--verbose] | 输出为执行changeset的行数 |
unexpectedChangeSets[--verbose] | 输出本地不存在changeset 行数 |
validate | 检查是否有错误的changelog |
calculateCheckSum <id> | 检查指定changeset id 的checksum值 格式为 filepath::id::author |
clearCheckSums | 从数据库日志中删除所有保存的校验和 |
changelogSync | 标记所有的更改已执行 |
changelogSyncSQL | 生成标记更改已执行的sql并输出到标准输出 |
markNextChangeSetRan | 将下一个变更标记为已执行 |
markNextChangeSetRanSQL | 生成将下一个变更标记为已执行的sql并输出到标准输出 |
listLocks | 列出liquibase数据库锁 |
releaseLocks | 释放所有的liquibase数据库锁 |
dropAll | 删除数据库表(慎用!) |
必传参数
参数 | 描述 |
---|---|
--changeLogFile=<path and filename> | 变更文件日志路径 |
--username=<value> | 数据库用户名 |
--password=<value> | 数据库密码 |
--url=<value> | 数据库url |
可选的参数
参数 | 描述 |
---|---|
--classpath=<value> | 类路径包含迁移文件和JDBC驱动程序 |
--driver=<jdbc.driver.ClassName> | 数据库驱动程序类名 |
--databaseClass=<database.ClassName> | 自定义liquibase.database。Databaseimplementation使用 |
--propertyProviderClass=<properties.ClassName> | 要使用的自定义属性实现 |
--defaultSchemaName=<name> | 要使用的默认数据库模式 |
--contexts=<value> | 更改要执行的上下文 |
--labels=<expression> | 定义要执行的标签变更集的表达式 |
--defaultsFile=</path/to/file.properties> | 带有默认选项值的文件(默认:./liquibase.properties) |
--delimiter=<string> | 与executeSql命令一起使用,用于设置用于分解包含多个语句的文件的字符串。 |
--driverPropertiesFile=</path/to/file.properties> | 在要创建的JDBC连接上设置自定义属性的文件 |
--changeExecListenerClass=<ChangeExecListener.ClassName> | 自定义更改Execlistener实现以使用 |
--changeExecListenerPropertiesFile=</path/to/file.properties> | 用于自定义更改Exec侦听器的属性 |
--liquibaseCatalogName=<name> | 带有liquibase表的目录的名称 |
--liquibaseSchemaName=<name> | 带有liquibase表的模式的名称 |
--databaseChangeLogTableName=<name> | Liquibase ChangeLogtable的名称(默认:DATABASECHANGELOG) |
--databaseChangeLogLockTableName=<name> | Liquibase ChangeLogLock表的名称(默认:DATABASECHANGELOGLOCK) |
--liquibaseSchemaName=<name> | 带有liquibase表的模式的名称 |
--includeSystemClasspath=<true|false> | 将系统类路径包含在Liquibase类路径中(默认:true) |
--promptForNonLocalDatabase=<true|false> | 如果非本地主机数据库(默认:false),则提示 |
--logLevel=<level> | 执行日志级别(调试、信息、警告、严重、关闭) |
--logFile=<file> | 日志文件 |
--currentDateTimeFunction=<value> | 覆盖SQL中使用的当前日期时间函数。适用于不受支持的数据库 |
--outputDefaultSchema=<true|false> | 如果为真,SQL对象引用包括模式名,甚至ifit也是默认模式。默认值为true |
--outputDefaultCatalog=<true|false> | 如果为真,SQL对象引用包括目录名,甚至ifit也是默认目录。默认值为true |
--outputFile=<file> | 为写入输出的命令写入输出的文件,例如updateSQL。如果没有指定,则写入sysout。 |
--help | 打印此消息 |
--version | 打印此版本信息 |
diff 命令必传参数
参数 | 描述 |
---|---|
--referenceUsername=<value> | 对比数据库用户名 |
--referencePassword=<value> | 对比数据库密码 |
--referenceUrl=<value> | 对比数据库url |
diff 命令可选参数
参数 | 描述 |
---|---|
--defaultCatalogName=<name> | 默认数据库目录 |
--defaultSchemaName=<name> | 默认数据库模式 |
--referenceDefaultCatalogName=<name> | 对比数据库要使用的参考数据库目录 |
--referenceDefaultSchemaName=<name> | 对比数据库要使用的数据库模式 |
--schemas=<name1,name2> | 从比较中包含对象的数据库模式 |
--referenceSchemas=<name1,name2> | 引用数据库模式来包含来自比较的对象,只有在与——模式不同时才需要 |
--outputSchemaAs=<name1,name2> | 在diffChangeLog/generateChangeLog上,使用这些名称作为schemaNameinstead of the real name。 |
--includeCatalog=<true|false> | 如果为真,则在生成的变更集中将目录默认为false |
--includeSchema=<true|false> | 如果为真,模式将包含在生成的changeSetsDefaults中 |
--referenceDriver=<jdbc.driver.ClassName> | 引用数据库驱动程序类名 |
--dataOutputDirectory=DIR | 以CSV格式输出给定目录中的数据 |
--diffTypes | diff类型的列表,包括inChange日志用一个逗号分隔 |
文章评论