在 Java 编程中处理模式变化
基于映射的框架需要模式、模型和映射。这样的框架是重复性的。请想像一下指定一个属性需要重复多少次:
模型中的 getter模型中的 setter模型中的实例变量映射的 “to” 端映射的 “from” 端列定义公平地讲,Hibernate 这样的 Java 框架通过代码生成的方式消除了不少重复工作。对象关系映射器可以处理遗留模式,对于新的数据库模式,可以用 Hibernate 提供的工具直接从模型生成模式并用 IDE 生成 getter 和 setter.可以用 Java 标注把映射嵌入域模型,但是按我的观点,这在一定程度上违背了使用映射的初衷。这种代码生成技术还有另一个用途:模式迁移。有些代码生成工具可以发现新的域模型和旧的模式之间的区别,并生成沟通这些不同的 SQL 脚本。请记住这些脚本处理的是模式,而不是数据。
例如,考虑这样一个迁移:把 first_name 和 last_name 这两个数据库列合并成叫作 name 的单一列。来自典型 Java 持久性框架的工具对数据库管理员没有帮助,因为这些工具只处理问题的一部分:模式中的变化。在进行这个模式变化时,还需要能够处理现有数据。在需要部署这个假想应用程序的新版本时,数据库管理员通常必须手工创建 SQL 脚本来完成以下工作:
创建叫作 name 的新列。
把 first_name 和 last_name 的数据放到新列中。
删除 first_name 和 last_name 列。
如果造成模式变化的代码版本仍然处在不完善的状态,那么经常必须手工回退变化。只有很少的团队有这个素养可以集成并自动进行跨模型、模式和数据的变化。
Rails 迁移基础
在 Rails 中,所有模式变化 —— 包括模式最初的创建 —— 都在迁移中发生。数据库模式中的每个变化都有自己的迁移对象,迁移对象包装了前进和后退。清单 1 显示了一个空迁移:
清单 1. 空迁移
class EmptyMigration < ActiveRecord::Migration
def self.up
end
def self.down
end
end
我很快将介绍如何调用迁移,但是现在请看看清单 1 中的迁移结构。在这个迁移的 up 方法中,要放置进行一个逻辑数据库变化所需的全部代码。还要捕获任何变化,从而能够取消模式变化。通过封装 up 和 down ,Rails 开发和生产工具可以自动进行涉及持久性对象模型的变化的部署和回退过程。这些数据库变化可能包括:
·添加或删除新表。
·添加或删除新列。
·以其他方式修改数据库,包括添加、删除或修改索引或其他约束。
·修改数据库数据。
通过允许改变数据,迁移大大简化了相关数据和模式的变化的同步过程。例如,可以添加一个查询表,把每个州和州的两位数字 ZIP 代码关联起来。在迁移中,可以填充数据库表,可能通过调用 SQL 脚本或装载 fixture.如果迁移正确,那么每个迁移都会把数据库置于一个一致的状态,不需要手工干预。
每个迁移的文件名都以一个惟一的编号开头。这个约定让 Rails 可以对迁移实现很强的排序。用这个策略,可以前后转移到逻辑数据库模式的任何状态。
