本文的目的是以最精炼的语言,理解什么是O/R Mapping,为什么要O/R Mapping,和如何进行O/R Mapping。
什么是O/R Mapping?
广义上,ORM指的是面向对象的对象模型和关系型数据库的数据结构之间的相互转换。
狭义上,ORM可以被认为是,基于关系型数据库的数据存储,实现一个虚拟的面向对象的数据访问接口。理想情况下,基于这样一个面向对象的接口,持久化一个OO对象应该不需要要了解任何关系型数据库存储数据的实现细节。
为什么需要O/R Mapping?
广义上,因为我们需要面向对象来描述我们的业务,我们也需要关系型数据库来存储我们的数据。
有人可能会提到,我们未必要用面向对象来描述业务,或者未必用关系型数据库来存储数据。没错,但是,至少,还是有相当大部分的程序,同时需要这两者的合作。存在即合理。因为同时需要彼此,两者都客观存在,就值得讨论。
既然从广义上,存在即合理,无需讨论为什么需要ORM,很多关于ORM的讨论,其实都是针对上面提到的狭义的定义。但是即使到目前为止,真正能够完美的实现这个狭义定义的ORM的工具,其实还并不存在(很多工具如Hibernate,已经相当接近,但是,离完美还有相当距离)。
既然还不存在,那么,在讨论需不需要之前,我们恐怕要先讨论一下,是否可能,即从理论上,从数学上,面向对象的对象模型和关系型数据库的数据结构之间,到底能不能做到完美的映射?要回答这个问题,我们要解决两个难题。
O/R阻抗失衡
第一个难题,叫“O/R阻抗失衡(O/R Impedance Mismatch)”,指的是OO对象模型和关系型数据库的数据结构之间的,设计理念上的差异。OO的设计理念,是以最正确的语义来描述真实世界;而关系型数据库的设计理念,则是从数学的角度,如何更有效的存储和管理数据。由于两者设计理念的差异,导致它们尽管从数据结构上,可能很相近,但是关注点往往是不同的。
例如:
- 从OO的角度,凡是语义明确,每一个对象语义上的属性,就应该定义为一个属性;从关系型数据库的角度,有可能考虑到一些属性从来不会被作为查询条件,而把多个语义上的属性,以一定的格式,存在一个数据表的字段中,也有可能因为一组语义上的属性使用的频度完全不同与另一组属性,即使他们语义上属于一个对象,也有可能将他们拆分成两个数据表来存储。
- 从OO的角度,对象只关心自己的固有属性