
简介Liquibase 4.31.0 Windows 版是面向数据库开发与运维人员的版本控制工具用于在多环境、多数据库间统一管理 schema 变更与回滚。该版本为 Windows 平台定制支持 MySQL、PostgreSQL、Oracle、SQL Server 等主流数据库适合引入 CI/CD 流程的团队使用。资源包共 134 个文件压缩后约 333.42MB主要包含 yaml 变更集、jar 依赖库、conf 配置文件、txt 说明文档及 batch 启动脚本等yaml 用于声明式定义数据库变更conf 便于对接 SQL*Plus 等客户端整体目录结构完整便于快速上手。已有 112 人学习下载。包内附带 README、GETTING_STARTED、changelog 等说明并提供 examples 示例与 lib 依赖文件夹能够帮助初学者理解从安装、配置到执行变更的完整流程也方便有经验的开发者直接复制示例改造为自己的数据库版本管理方案。 做后端开发这几年我经历过最痛苦的事情之一就是数据库表结构变更全靠口头通知。开发手里一套表结构、测试环境一套、生产环境又是一套上线前对脚本对到怀疑人生。后来开始用Liquibase情况才算彻底转变。今天这篇就聊聊我刚在Windows上部署的liquibase-4.31.0从下载安装到配置执行把我踩过的坑和整理好的用法一次性列清楚尤其是Windows环境下那些和控制台、路径、驱动相关的问题。如果你是刚接触数据库版本管理或者已经在项目里用Flyway正纠结要不要换Liquibase这篇文章也适用。我会在第一章先把选型问题讲透再进入Windows环境下的实操保证你看完就能动手。1. 为什么我选了Liquibase而不是Flyway很多团队在刚开始做数据库版本管理时第一个遇到的决策就是“Liquibase还是Flyway”。这个问题的答案没有绝对的对错但有个大前提如果你们团队规模不大、表结构不复杂、只用PostgreSQL或者MySQL而且希望“拿来就用”Flyway确实省心。但如果项目涉及多种数据库、变更需要精细化控制或者在大型组织里需要强规范Liquibase是更稳的选择。1.1 两款主流迁移工具的核心差异先说原理。Flyway的核心思路是“按版本号顺序执行SQL脚本”它的工作方式简单直接维护一张flyway_schema_history表记录哪些脚本被执行过每个脚本有个版本号如V1__create_table.sql执行顺序严格按版本号来。Liquibase的思路则是“描述变更意图”用changelog文件描述数据库的期望状态Liquibase自己根据记录在DATABASECHANGELOG表中的id和author来决定哪些变更需要执行。两者最直观的差异在changelog格式上。Liquibase支持XML、YAML、JSON和SQL四种格式你可以把变更写成数据库无关的XML或YAMLLiquibase会翻译成目标数据库的方言Flyway则严格以SQL为中心。这让Liquibase在异构数据库迁移、多环境部署上有明显优势。比如你从MySQL迁到PostgreSQLLiquibase只需要改URL大部分逻辑不用动Flyway的SQL脚本则需要你手动改写。回滚能力是另一个分水岭。Flyway的“回滚”其实是通过独立脚本实现的如U__rollback本质上不是自动回滚Liquibase则可以在changeSet中定义rollback标签或者利用内置逻辑自动生成部分回滚语句配合rollbackCount、rollbackToTag等命令执行精确回滚。生产环境出问题需要快速回退时这个差别能省下大把时间。执行流程上Liquibase还多了preConditions、contexts、labels这些概念。preConditions可以在执行前检查表是否存在、列类型是否符合预期不满足就跳过或报错contexts类似环境标签标识某段变更只在test或prod下执行。Flyway也有baseline、validate等机制但精细化控制能力相对薄弱。1.2 Liquibase 4.31.0到底适合谁如果你正在犹豫要不要用4.31.0这个版本我的建议是能用新版本就用新版本。Liquibase的发布节奏很快每个小版本都会修掉一批连接器问题、命令参数问题4.31.0属于2025年上半年的版本对JDK 11、17的兼容性已经打磨得很稳定同时对MySQL、PostgreSQL、Oracle、SQL Server这些主流数据库都有成熟的内置连接器支持。那到底什么样的人适合上Liquibase我个人的判断标准是数据库变更是否已经成了你上线的瓶颈。如果你的项目只有几张表、一个月才改一次表结构用Excel维护变更记录就够了如果你天天在改表结构或者系统需要同时支持多种数据库再或者你们有DBA需要提前审核变更SQL那就值得引入Liquibase。尤其是“DBA审核”这个场景Liquibase的update-sql命令可以把所有待执行SQL先输出到本地审完再执行这点是Flyway很难比的。还要说明一个概念Liquibase本质是一个Java程序所以“Windows版本”并不是说它针对Windows平台重新实现了内核而是指官方为Windows用户提供了zip免安装包和执行脚本liquibase.bat。你在Windows上用的还是同一套核心程序只不过启动入口和路径处理、编码处理上要按Windows的规矩来。这一块恰恰是很多坑的集中地下面重点说。2. Windows环境准备与安装目录规划2.1 4.31.0对Java版本的要求我先说一个最常见的坑Liquibase 4.31.0要求JDK 11及以上版本如果你机器上装的是Java 8启动时会直接报UnsupportedClassVersionError。检查办法很简单在cmd里执行java -version确认显示的版本号。如果还没装Java建议直接装JDK 17因为从4.x版本开始Liquibase官方对17的测试覆盖最好而且长支持版本也更稳定。装完Java后记得把JAVA_HOME环境变量配好指向JDK安装根目录比如C:\Program Files\Java\jdk-17再把%JAVA_HOME%\bin加入Path。很多Liquibase在Windows下启动失败最后排查下来就是JAVA_HOME没配对。这里有个小细节如果你同时装了多个JDK版本cmd里敲java -version显示的可能是Path中最靠前的那个。所以配置完环境变量后最好新开一个cmd窗口再验证一遍因为旧窗口不会刷新环境变量。2.2 安装包解压与PATH配置Liquibase 4.31.0的Windows安装包是一个zip文件解压出来只有一个目录我通常放在C:\tools\liquibase-4.31.0目录里面最关键的文件是liquibase.bat和liquibase后者是Linux/macOS用的脚本Windows下不用管。解压完成后需要设置两个环境变量LIQUIBASE_HOMEC:\tools\liquibase-4.31.0 Path 追加 ;%LIQUIBASE_HOME%然后新开一个cmd窗口执行liquibase --version如果看到类似下面的输出说明安装成功Liquibase Version: 4.31.0 Liquibase Community: 4.31.0如果你在系统设置里配好了环境变量但cmd还是提示“不是内部或外部命令”大概率是当前窗口没有重新打开。另一个容易被忽略的点是用户级环境变量和系统级环境变量优先级不同如果两个层级都配置了不同值可能会覆盖掉你期望的路径。还要注意一个Windows特有的问题路径含空格。如果你把Liquibase装在了C:\Program Files\下liquibase.bat里的脚本逻辑虽然会自动处理但你自己在写LIQUIBASE_HOME时不要加引号系统会在使用Path时自动处理。更省心的方案是像我一样直接选一个没有空格的路径比如C:\tools\能避免很多莫名其妙的坑。3. 核心配置与首个changelog编写3.1 liquibase.properties里的参数详解Liquibase可以在命令行里传参但连数据库的URL、账号密码每回都写一遍太痛苦尤其当密码里带着、#这些特殊字符时在cmd里转义会转得你怀疑人生。所以我强烈推荐在项目根目录准备一个liquibase.properties文件把公共参数固化下来。这是我常用的一个示例以MySQL为例changeLogFiledb/changelog.xml urljdbc:mysql://localhost:3306/app_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 usernameroot passwordyour_password_here drivercom.mysql.cj.jdbc.Driver这里有几个参数需要细说。changeLogFile指定的是changelog文件路径注意它是相对于liquibase.properties所在目录的我习惯在项目根目录下建一个db文件夹来放changelog。url里的serverTimezoneAsia/Shanghai不是可选项MySQL 8的驱动如果不指定时区连接时会直接报错。driver参数在大部分情况下可以不写Liquibase会根据URL自动推断但如果你把驱动jar放得比较偏或用了老版本驱动手动指定更保险。还有一个容易被忽略的参数liquibase.hub.apiKey。4.31.0版本在启动时会提示你登录Liquibase Hub账号如果不配置API Key也不会阻塞命令但会多一段提示。如果你被提示困扰网上搜索“liquibase.hub.apiKey off”会有一个关闭方案更简单的做法是忽略它因为不影响实际使用。3.2 编写changelog并跑通第一次迁移changelog是Liquibase的灵魂。4.31.0推荐使用dbchangelog-latest.xsd作为XML的schema下面是建一张用户表的例子?xml version1.0 encodingUTF-8? databaseChangeLog xmlnshttp://www.liquibase.org/xml/ns/dbchangelog xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd changeSet id20250401-1 authoritsme createTable tableNameuser_info column nameid typebigint autoIncrementtrue constraints primaryKeytrue nullablefalse/ /column column nameusername typevarchar(50) constraints nullablefalse uniquetrue/ /column column namecreated_at typetimestamp constraints nullablefalse/ /column /createTable /changeSet /databaseChangeLog这个XML的核心是changeSet里面的id和author联合起来作为这条变更在数据库中的唯一标识。Liquibase执行时会查DATABASECHANGELOG表只要发现相同idauthor的记录就会跳过这条变更所以id一旦定下来就不要轻易改改id等于让Liquibase认为这是一条新变更会在生产环境重复执行这是新手最容易踩的雷。第一次执行时在项目目录下运行liquibase update如果一切正常Liquibase会输出一系列日志显示创建了DATABASECHANGELOG表、执行了你的changeSet。这时候去数据库里看应该能看到user_info表同时还会多出DATABASECHANGELOG和DATABASECHANGELOGLOCK两张表。前者记录变更历史后者用于锁控制防止多人同时执行迁移导致冲突。这里我再强调一下编码问题changelog文件在Windows上一定要保存为UTF-8不要用GBK。如果你是修改既有文件经常会发生“文件看起来没问题但Liquibase执行时报XML解析错误”这时候先怀疑编码。像VS Code、Notepad都可以在右下角看到当前文件编码保存时注意选择UTF-8 without BOM。4. 常用命令实操update、updateSQL与rollback4.1 4.31中命令参数的大变化如果你在网上搜过Liquibase教程很多老文章的写法是--changeLogFile...注意这个写法在4.31.0里已经行不通了。Liquibase从4.24版本开始逐步把命令行参数从驼峰式改成了短横线式到4.31.0旧参数基本被移除。正确写法是这样的liquibase --change-log-filedb/changelog.xml --urljdbc:mysql://localhost:3306/app_db --usernameroot --password123456 update同样的参数还有--default-schema-name以前是--defaultSchemaName、--default-catalog-name等。如果你不确定某个参数在当前版本里怎么写最好的办法是执行liquibase --help查看帮助文档输入liquibase update --help还能看到该命令支持的全部参数。顺带提一下如果你在用PowerShell执行Liquibase命令需要注意PowerShell对$符号有特殊解释比如URL里有?和这种字符时建议用单引号把整个参数值包起来liquibase --change-log-filedb/changelog.xml --urljdbc:mysql://localhost:3306/app_db?useSSLfalse update4.2 生产发布最稳的三步走在开发环境里直接liquibase update没问题但生产环境为了稳妥我总结了一套三步走流程强烈推荐用起来。第一步生成SQL脚本。使用update-sql命令老版本叫updateSQL不会直接改数据库而是把所有待执行的SQL语句打印出来liquibase --change-log-filedb/changelog.xml --urljdbc:mysql://localhost:3306/app_db update-sql predeploy.sql生成的predeploy.sql可以交给DBA审阅确认没有问题后再在生产环境执行真正的update。这里有个好处你能提前看到Liquibase为这个changeSet生成的具体DDL如果有不合适的列类型或索引定义可以在这一步发现而不是等上了生产再回滚。第二步执行前打标签。在希望回滚到的位置打一个tagliquibase tag v1.0.0这个命令不会改变数据库结构只在DATABASECHANGELOG里记录一条标记。后续如果发版出问题可以用rollbackToTag直接回到当前状态。第三步执行正式变更liquibase update万一上线后出问题回滚时根据情况选择# 按次数回滚比如回滚最近1次变更 liquibase rollbackCount 1 # 回滚到指定tag liquibase rollbackToTag v1.0.0 # 回滚到指定时间点 liquibase rollbackToDate 2025-04-01T10:00:00关于回滚我要提醒一点不是所有changeSet都能自动生成回滚语句。比如dropColumn这种操作Liquibase可以自动生成反向的addColumn但有些复杂操作尤其涉及数据库特定行为时自动回滚可能不准确。稳妥的做法是在changeSet中显式声明rollback块changeSet id20250401-2 authoritsme addColumn tableNameuser_info column nameage typeint/ /addColumn rollback dropColumn tableNameuser_info columnNameage/ /rollback /changeSet这样rollback时就有明确的执行计划不会依赖Liquibase的自动推断。如果你没写rollback且Liquibase无法自动生成执行回滚时会报错并提示缺少回滚语句。5. Windows平台常见问题与排查技巧5.1 中文乱码与控制台输出Windows控制台默认代码页是GBK编码936而Liquibase默认按UTF-8输出日志这就导致控制台里的中文提示变成乱码。现象通常是日志中所有中文字符变成锟斤拷或类似乱码。解决方法是执行命令前先切换代码页chcp 65001 liquibase updatechcp 65001把控制台代码页切到UTF-8。但注意这个切换只在当前cmd窗口生效关掉窗口就恢复原样所以每次都要执行。如果你嫌麻烦可以在changelog文件里写成英文注释或者接受控制台乱码只在使用liquibase --help时出现、实际执行不受影响这一现状。更隐蔽的乱码问题发生在changelog内容里。比如你在XML里写了中文注释或者varchar列里要插入中文数据如果文件编码不是UTF-8执行时会报Invalid character data或数据写入后是乱码。这就要回到我之前说的文件保存时务必选UTF-8 without BOM。很多Windows编辑器默认存成GBK这个坑我遇到不止一次。5.2 驱动加载与ClassNotFoundLiquibase不带MySQL、PostgreSQL的JDBC驱动你连接什么数据库就得自己准备对应的驱动jar。最常见的报错是Could not find driver: com.mysql.cj.jdbc.Driver解决办法是下载对应的JDBC驱动jar放到Liquibase安装目录的lib文件夹下。如果你使用Maven或Gradle管理依赖也可以从本地Maven仓库把驱动jar拷贝过来。这里有个细节Liquibase 4.31.0的目录结构里有一个internal子目录里面确实内置了一些驱动比如HSQLDB但常用数据库驱动还是得自己准备。放jar时注意版本MySQL 8用mysql-connector-j-8.x.x.jarPostgreSQL用postgresql-42.x.x.jar老版本的驱动可能导致连接报错。如果已经放了驱动但还是报ClassNotFound先检查jar是否损坏可以直接用压缩软件打开看看里面有没有com/mysql/cj/jdbc/Driver.class这个路径。还有一个坑某些下载平台会给你一个带版本后缀的jar包名比如mysql-connector-j-8.0.33.jarLiquibase加载时按文件名扫描正常没问题但如果你手动改过文件名导致扩展名不对就会加载失败。5.3 其他高频坑除了上面两类Windows下还会遇到几个常见问题。PowerShell执行liquibase命令时提示“无法加载文件因为在此系统上禁止运行脚本”。这是因为PowerShell默认执行策略是Restricted不允许运行.ps1脚本。解决方案是用cmd窗口执行或者临时放开策略Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope ProcessLiquibase执行到一半中断再次执行提示Liquibase Lock相关错误。这是因为DATABASECHANGELOGLOCK表中记录了锁信息上次执行没有正常释放。等你确认没有其他进程在跑Liquibase后可以清理锁。4.31.0提供了liquibase release-locks命令来强制释放锁不用手动去删表数据。还有一个容易被忽视的问题如果你在Spring Boot项目里已经集成了Liquibase又想在命令行手动执行liquibase update要确保两者的changelog配置一致否则会出现Spring Boot启动时跑了一遍、命令行又跑一遍虽然Liquibase会用idauthor去重但历史记录会变得很乱。最后说一个我在真实项目里的体会。Liquibase在Windows命令行下虽然能跑通但团队协作时不建议每个人都去敲命令最好是把liquibase update固化到CI流水线里或者通过Maven/Gradle插件在构建阶段自动执行。命令行更多用于本地开发、问题排查和紧急回滚。你会发现当数据库变更进入版本管理、可以像代码一样被review、被追溯时上线前的那种紧张感会少很多。如果你在Windows上折腾Liquibase 4.31.0时遇到了上面没提到的怪问题我给你的排查路线是先看Java版本和JAVA_HOME再看驱动jar和编码最后检查命令参数命名。按这个顺序来基本能定位90%以上的问题。本文还有配套的精品资源点击获取