假设你正在使用Hibernate和JBoss开发Java EE应用程序。 你有一个运行中的服务器上存储着一些重要数据。 你每隔一段时间(1-2周)发布一次应用程序的下一个版本,并在持久层中进行一堆更改:
- 新增实体
- 删除实体
- 属性类型更改
- 属性名称更改
- 关联关系更改
如何有效地设置一个系统来更新数据库架构并保留数据? 据我所知(我可能错了),Hibernate不执行alter column、drop/alter constraint等操作。
谢谢, Artem B.
假设你正在使用Hibernate和JBoss开发Java EE应用程序。 你有一个运行中的服务器上存储着一些重要数据。 你每隔一段时间(1-2周)发布一次应用程序的下一个版本,并在持久层中进行一堆更改:
如何有效地设置一个系统来更新数据库架构并保留数据? 据我所知(我可能错了),Hibernate不执行alter column、drop/alter constraint等操作。
谢谢, Artem B.
LiquiBase是您的最佳选择。它有一个Hibernate集成模式,使用Hibernate的hbm2ddl来比较数据库和Hibernate映射,但不会自动更新数据库,而是输出一个Liquibase变更记录文件,可在实际运行前进行检查。
虽然更方便,但任何对数据库和Hibernate映射进行比较的工具都可能出现错误。请参见http://www.liquibase.org/2007/06/the-problem-with-database-diffs.html以获取示例。使用Liquibase,您可以建立一个数据库更改列表,以便在开发过程中,格式能够在代码分支和合并时生存。
我个人会跟踪迁移SQL脚本中的所有更改。
driver: com.mysql.jdbc.Driver
classpath: lib\\mysql-connector-java-5.1.30.jar
url: jdbc:mysql://localhost:3306/OLDdatabase
username: root
password: pwd
liquibase diffChangeLog --referenceUrl="jdbc:mysql://localhost:3306/NEWdatabase"
--referenceUsername=root --referencePassword=pwd > C:\Users\ME\Desktop\Migration.xml
java -jar liquibase.jar --changeLogFile="C:\Users\ME\Desktop\Migration.xml" update
我使用了Hibernate内置的SchemaUpdate来处理一个应用程序,直接在引导类中使用,这样每次启动应用程序时都会检查模式。这可以处理添加新列或表的情况,这通常是成熟应用程序中发生的事情。为了处理特殊情况,例如删除列,引导程序只需手动在try/catch中运行ddl,因此如果已经删除一次,它只会静默地抛出错误。我不确定在生产应用程序中处理关键数据是否适用,但在几年和数百次部署中,我从未遇到过问题。
你也可以使用DBMigrate。它类似于Liquibase:
这个库与Ruby on Rails的'rake migrate'类似,它允许你管理Java应用程序的数据库升级。
http://www.hibernate.org/hib_docs/tools/reference/en/html/ant.html#d0e1137
update(默认值:false):尝试创建一个更新脚本,表示数据库中的内容与映射之间的“增量差异”。忽略创建/更新属性。(不要用于生产数据库,无法保证可以生成正确的增量或底层数据库能够执行所需的操作)