ORM不是新概念,但还是容易与Active Record和Data Mapper混淆,这里就来快速分清他们。
⎮ORM
⎮定义
ORM是Object-Relational Mapping的缩写,也叫O/RM,O/R Mapping,是一种计算机编程思想,它使用面向对象编程语言,在两种不同类型系统之间进行数据转换。
ORM是位于应用和数据库之间的一层,用于实体对象(例如 POJO)和关系数据(数据库表的行)之间的转换。
⎮理解
ORM旨在建立领域模型(也称为实体对象,例如 POJO)和数据库表之间的映射,它是对实体对象的操作。例如新增操作,就是新建一个实体对象,将数据传给对象,然后执行存储操作(ORM负责建立实体对象的属性和数据库表的字段的对应,然后自动生成insert SQL语句并执行,将数据持久化到数据库);
ORM就像一个“虚拟的对象数据库”,是内存中一个对象集合,表示关系数据在内存中的“映射”。
ORM让你“忘记”表的存在,通过操作ORM对象和属性实现对数据库表和字段的操作。
ORM是一种思想,它有两种实现模式:Active Record(活动记录)和Data Mapper(数据映射器)。

⎮Active Record
⎮理解
Active Record常翻译为活动记录,下面沿用。
活动记录是ORM的一种形式,每一个活动记录就是一条关系数据。
每个活动记录对象都继承一个基础Active Record对象,这样它就会拥有所有数据库操作方法。
每个活动记录对象包括数据和方法,数据和数据库表的字段相对应,方法对应数据库表的持久化操作,例如CRUD;
最著名的活动记录框架是Ruby On Rails,下面使用RoR演示。
⎮示例
class User < ApplicationRecordend
user = User.find_by(name: 'David')user.name = 'Dave'user.save
是不是很简单?
៲ 活动记录简单、直观、易于理解、便于学习,适合快速搭建项目,但不适合复杂业务场景;
៲ 活动记录设计简单,每个活动记录代表一行关系数据,例如一个User对象表示一行user记录及其CRUD操作,但它不能和Product交互,体现不出“相关数据”,不是合适的面向对象设计;
៲ 活动记录将业务逻辑和数据访问强耦合,从而降低代码可维护性和扩展性,不适合大型应用;
៲ 有观点甚至认为活动记录是反模式,我觉得只是Data Mapper常翻译为系统复杂度的上升,新技术的出现,但依然有大量应用场景可以使用活动记录;
⎮理解
Active Record常翻译为数据映射器,下面沿用。
数据映射器是位于实体对象和数据库之间的一个数据访问层(是不是有点像ORM?),用于在二者之间传递数据,同时保持实体对象、数据库和映射器之间的相互独立性。
这一层一般包含多个映射器,用来实现各自模型的数据传输。
和活动记录最大的不同,数据映射器将领域模型(实体对象)和持久层(CRUD)相分离,意味着每个实体对象并不知道它是如何存储到数据库中的,这个会由“专业”的层去实现。
相比活动记录,数据映射器更接近ORM思想。
⎮示例
实体定义:
@Entitypublic class Product {@Idprivate Integer id;private String name;public Product() {}// getter setter ...}
@Componentpublic class ProductDao {@PersistenceContextprivate EntityManager em;public void persist(Product product) {em.persist(product);}public List<Product> findAll() {return em.createQuery("SELECT p FROM Product p").getResultList();}}
៲ 领域建模概念,适合业务复杂的大型应用;
៲ 符合面向对象“低耦合”原则,领域模型和持久层相互分离,通过映射建立关系;
៲ 抽象层度更高,实现稍微复杂;
⎮应用场景
两种模式各有利弊,需要根据应用类型和场景判断选择:
1. 应用类型
如果项目是“数据思维”,是由CRUD操作组成的简单系统,没有复杂业务逻辑,活动记录可以快速搭建和启动,例如Ruby on Rails框架就用来快速搭建web应用;
如果项目是“领域思维”,是由业务规则和流程组成的复杂系统,数据映射器可以通过实体对象封装领域模型,例如Hibernate ORM就用来实现数据映射。
2. 应用场景
如果你在做MVP,需要快速搭建产品原型,可以使用活动记录模式;
如果你工作在遗留系统,或者拥有大量领域知识,需要抽象领域对象,那么数据映射器更适合。




