【发布时间】:2018-04-07 23:30:48
【问题描述】:
我的目标是为现有应用程序启用架构和数据迁移。
这种问题好像被问过很多次了,不过我觉得和我的要求和情况不同。
由于我在这个领域缺乏经验,请允许我先列出应用程序的架构和我的假设。
架构
该应用程序是一个多用户企业桌面应用程序,其后端服务器可以持久保存到任何主要数据库(MySql、Postgresql、SQL Server、Oracle DB 等)。假设数据库在本地并由我们的客户维护。
使用的技术栈是相当常见的 Hibernate+Spring+RMI/JMS-Combo。
目前,迁移由服务器通过以下方式完成:
- 在服务器启动时,它会检查最新的预期架构版本
- 如果大于当前版本,则开始迁移到下一个版本,直到 current==latest:
- 创建新数据库
- 加载(整个)最新架构(带有大量
CREATE TABLE ...的 SQL 脚本) - 迁移数据(在 Java 类中使用 2 个 JDBC 连接到新旧模式)
- 加载(全部)最新约束(包含大量
ALTER TABLE ...的 SQL 脚本)
此迁移缓慢且仅向前迁移。但这很简单。问题是,到目前为止,数据迁移中的模式脚本和查询一直使用 MySQL 语法和功能。
请注意,迁移数据我的意思是:后端服务器将数据从旧模式复制到新模式,并在必要时对其进行转换。 此外,迁移过程会在我们的客户内部自动启动。这意味着,我们只能控制 JDBC 连接,但不能直接访问数据库,也不能了解正在使用的特定数据库(MySQL、SQL Server 等)。
目标是用独立于数据库的迁移方案替换或扩充此迁移方案。
假设和研究
StackOverflow 1 2 3 4 5 6 7:回答状态以使用 Hibernate 的内置功能。但是,文档声明这不是production ready。此外,AFAICT,所有答案都与仅架构迁移有关。
Liquibase:使用自定义 DSL(在 XML/JSON/YAML/等中)以允许独立于数据库的仅模式迁移。
DBUnit:使用自定义 XML-DSL 捕获数据库状态的快照。 无法重新创建架构版本 1 到版本 2 的快照。
flyway: 原则上与 Liquibase 相同。但不是独立于数据库的,因为 SQL 脚本用于迁移。
JOOQ:基于 JDBC 的 Java 中独立于数据库的 Query-DSL。与 Criteria API 相当,但没有 JPA 的缺点。原则上应该允许独立于数据库的数据迁移,但是,不有助于架构迁移。
HQL、JPQL、Criteria API 等 JPA 查询语言是不够的,因为
- 无法引用实体管理器未映射的表。例如。联接表、元数据和审计表。
- 需要为映射保留所有版本的实体类的副本。
问题
我意识到,就目前这个问题而言,它将被视为基于意见而被驳回。
但是,我不一定要寻找这个问题的具体解决方案(我怀疑对于如此复杂的问题空间是否存在明确的解决方案),而是要验证我的假设。
也就是说,是不是真的,那个
- Liquibase 和 Flyway 主要关注架构迁移,而数据迁移留给读者作为练习?
- 为了让 Flyway 支持多个不同的数据库,是否需要为每个数据库复制迁移脚本?
- 总的来说,独立于数据库的数据迁移问题在企业 Java 中仍未解决?
即使我将 Liquibase/Flyway 与 JOOQ 结合使用,我也看不到如何执行数据迁移,因为 Liquibase/Flyway 迁移数据库就地。旧数据库被破坏,并有机会将旧数据转换为新模式。
感谢您的关注!
【问题讨论】:
标签: java hibernate database-migration liquibase flyway