SpringBoot项目实战:5分钟搞定Liquibase多数据库迁移(PostgreSQL/MySQL双配置)

张开发
2026/4/16 14:30:44 15 分钟阅读

分享文章

SpringBoot项目实战:5分钟搞定Liquibase多数据库迁移(PostgreSQL/MySQL双配置)
SpringBoot实战5分钟实现Liquibase多数据库动态迁移方案在企业级应用开发中数据库迁移工具的选择往往决定了团队协作效率和系统可维护性。最近接手的一个金融项目需要同时支持PostgreSQL和MySQL两种数据库这让我重新审视了Liquibase在多数据库环境下的实战价值。与常见的单数据库配置不同多数据库支持需要考虑更多细节——从SQL方言差异到事务处理机制每个环节都可能成为项目后期的技术债。1. 环境准备与基础配置1.1 依赖引入策略多数据库支持的首要问题是依赖管理。在pom.xml中我们需要同时引入两种数据库驱动但要注意避免版本冲突dependencies !-- PostgreSQL驱动 -- dependency groupIdorg.postgresql/groupId artifactIdpostgresql/artifactId version42.3.1/version /dependency !-- MySQL驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.28/version scoperuntime/scope /dependency !-- Liquibase核心库 -- dependency groupIdorg.liquibase/groupId artifactIdliquibase-core/artifactId version4.15.0/version /dependency /dependencies提示建议将数据库驱动版本提取到properties节点统一管理特别是当项目中使用Spring Boot的dependency management时1.2 动态数据源配置application.yml的配置需要支持环境切换。以下是经过生产验证的配置模板spring: profiles: active: dev-postgres # 默认使用PostgreSQL开发环境 liquibase: change-log: classpath:db/changelog/master.xml enabled: true --- # PostgreSQL开发配置 spring: config: activate: on-profile: dev-postgres datasource: url: jdbc:postgresql://localhost:5432/app_db username: postgres password: postgres123 driver-class-name: org.postgresql.Driver --- # MySQL生产配置 spring: config: activate: on-profile: prod-mysql datasource: url: jdbc:mysql://prod-db:3306/app_db?useSSLfalseallowPublicKeyRetrievaltrue username: app_user password: mysql123 driver-class-name: com.mysql.cj.jdbc.Driver这种配置方式允许通过启动参数--spring.profiles.activeprod-mysql快速切换数据库环境。2. 多数据库迁移脚本设计2.1 主变更日志结构在resources/db/changelog目录下建立如下结构db/ └── changelog/ ├── master.xml # 主入口文件 ├── v1.0/ # 版本目录 │ ├── init-schema.xml │ └── seed-data.xml └── common/ # 公共脚本 ├── functions.xml └── procedures.xmlmaster.xml作为入口文件采用include方式组织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-4.15.xsd include relativeToChangelogFiletrue filev1.0/init-schema.xml/ include relativeToChangelogFiletrue filev1.0/seed-data.xml/ /databaseChangeLog2.2 数据库差异处理技巧2.2.1 条件执行策略利用Liquibase的preConditions实现多数据库适配changeSet idcreate-sequence authordev_team preConditions onFailMARK_RAN dbms typepostgresql/ /preConditions createSequence sequenceNameuser_id_seq startValue1000 incrementBy1/ /changeSet changeSet idauto-increment authordev_team preConditions onFailMARK_RAN dbms typemysql/ /preConditions addAutoIncrement tableNameusers columnNameid columnDataTypebigint/ /changeSet2.2.2 通用SQL与方言SQL结合对于兼容性较好的操作可以使用通用XML语法特殊需求则用sql标签changeSet idcreate-user-table authordev_team createTable tableNameusers column nameid typebigint constraints primaryKeytrue nullablefalse/ /column column nameusername typevarchar(50) constraints nullablefalse uniquetrue/ /column /createTable sql dbmspostgresql COMMENT ON TABLE users IS 系统用户表; /sql sql dbmsmysql ALTER TABLE users COMMENT 系统用户表; /sql /changeSet3. 高级配置与优化3.1 多环境参数化配置在changelog中使用属性替换提高灵活性property nameschema_name valueapp_schema context!test/ property nameschema_name valuetest_schema contexttest/ changeSet idcreate-schema authordev_team sql dbmspostgresql CREATE SCHEMA IF NOT EXISTS ${schema_name}; /sql sql dbmsmysql CREATE DATABASE IF NOT EXISTS ${schema_name}; /sql /changeSet3.2 变更集校验策略针对不同环境配置不同的校验规则spring: liquibase: parameters: strictCheck: true # 生产环境严格检查 contexts: prod # 生产环境上下文对应的变更集配置changeSet idcritical-update authorsenior_dev contextprod preConditions onFailHALT runningAs usernamedeploy_user/ /preConditions !-- 关键变更内容 -- /changeSet4. 实战问题解决方案4.1 常见兼容性问题处理自增主键处理差异changeSet idhandle-auto-increment authordev_team createTable tableNameproducts column nameid typebigint autoIncrementtrue constraints primaryKeytrue/ /column /createTable modifySql dbmspostgresql append valueALTER TABLE products ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY/ /modifySql /changeSetJSON类型支持changeSet idadd-json-column authordev_team addColumn tableNameproducts column namespecs typejsonb dbmspostgresql/ column namespecs typejson dbmsmysql/ /addColumn /changeSet4.2 性能优化技巧批量插入优化方案changeSet idbulk-insert authordev_team loadData filedb/changelog/data/products.csv tableNameproducts separator, usePreparedStatementstrue column nameid typenumeric/ column namename typestring/ /loadData sql dbmspostgresql ANALYZE products; /sql sql dbmsmysql ANALYZE TABLE products; /sql /changeSet索引创建最佳实践changeSet idcreate-indexes authordba_team createIndex tableNameorders indexNameidx_orders_user uniquefalse column nameuser_id/ /createIndex sql dbmspostgresql CREATE INDEX CONCURRENTLY idx_orders_created ON orders(created_at); /sql sql dbmsmysql splitStatementstrue SET SESSION innodb_online_alter_log_max_size256000000; ALTER TABLE orders ADD INDEX idx_orders_created (created_at), ALGORITHMINPLACE, LOCKNONE; /sql /changeSet在最近的项目中我们发现Liquibase的runInTransaction属性对MySQL的DDL操作有特殊影响。当设置为false时某些ALTER TABLE操作会意外提交当前事务。经过多次测试最终确定在MySQL环境下该属性应该始终保持默认值true而在PostgreSQL中可以根据操作类型灵活调整。

更多文章