1、什么是 对象-关系映射

  对象-关系映射(Object Relational Mapping,简称ORM,对象关系映射)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。

  对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的 两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多 关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

  对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的 两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多 关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

  让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。

  一般的ORM包括以下四部分: 
      一个对持久类对象进行CRUD操作的API; 
      一个语言或API用来规定与类和类属性相关的查询; 
      一个规定mapping metadata的工具; 
      一种技术可以让ORM的实现同事务对象一起进行dirty checking(脏检查), lazy association fetching(惰性关联抓取)以及其他的优化操作。

2、目前流行的 ORM 产品

      目前众多厂商和开源社区都提供了持久层框架的实现,常见的有:      Apache OJB (http://db.apache.org/ojb/) 

      Cayenne (http://objectstyle.org/cayenne/) 

      Jaxor (http://jaxor.sourceforge.net) 

      Hibernate (http://www.hibernate.org) 

      iBatis (http://www.ibatis.com) 

      jRelationalFramework (http://ijf.sourceforge.net) 

      mirage (http://itor.cq2.org/en/oss/mirage/toon) 

      SMYLE (http://www.drjava.de/smyle) 

      TopLink (http://otn.oracle.com/products/ias/toplink/index.html)      其中 TopLink 是 Oracle 的商业产品,其他均为开源项目。      其中 Hibernate 的轻量级 ORM 模型逐步确立了在 Java ORM 架构中领导地位,甚至取代复杂而又繁琐的 EJB 模型而成为事实上的 Java ORM 工业标准。而且其中的许多设计均被 J2EE 标准组织吸纳而成为最新 EJB 3.0 规范的标准,这也是开源项目影响工业领域标准的有力见证。

3、对象-关系映射模式

  (1)数据类型映射模式

  • 简单数据类型模式:建立UML和关系型数据库中简单数据类型的映射表以指导映射。

  • 枚举数据类型模式:每种枚举类型对应一个表,只有一个列(_EnumLiteral)表示枚举值。

  • 基于类的数据类型模式:使用外键约束,将基础列与基于类的类型实例相关联。

  (2)类映射模型

      每个类对应一个表。单值属性、多值属性、继承关系可以用下述方法映射,而引用属性将在关联映射模式中提到。

  • 单值属性模式:是cardinality的上界为1的属性,映射到类所对应的表的列上。若其下界也为1(必须有的属性),列属性为NOT NULL。
  • 多值属性模式:每个多值属性映射成一个独立的表,使用外键连接到类所对应的表上。

  • 继承模式:每加入一个类的实例时,根据其继承关系自顶向下生成每个类的对象,这些对象具有相同的ID(根对象对应记录的主键)。删除对象实例时,自底向上删除数据。

  (3)关联映射模式

  • 一对一关联模式:在关联两端各加一列。

  • 一对多关联模式:如果多这端是有序的,还需加入一列表示序号。

  • 多对多关联模式:将关联单独作一个表。

  • 组合关联模式:注意级联式删除。

  • 反演关联模式:关联两端指向相关的类型,和普通关联一样。

  • 成对关联模式:关联记录两个类间的关系,用交集类表示关联,表示成一个单独的表,每个关联对应一个表,用外键表示它们间的关系。

  • 关联上的OCL需要分析成对应的存储过程代码。

  • 保证关联的cardinality也需要分析成对应的存储过程代码。

  (4)引用映射模式

  • 在UML中不存在的MOF特征,指属性是声明为引用类型的实例。用存储过程实现。

4、SQL与ORM的优缺点

相对来说,ORM的缺点就是SQL的优势地方,而优点也是SQL的劣势地方。

  • ORM优点
    • 方便地使用面向对象,语句清晰

    • 防注入『这个其实不算ORM的核心,因为比如Phalcon的SQL形式写法也可以防注入』

    • 方便动态构造语句,对于不同的表的相同操作采用多态实现更优雅

    • 一定程度方便重构数据层『比如改表名,字段名等』

    • 设置钩子函数

  • ORM缺点
    • 不太容易处理复杂查询语句
    • 性能较直接用SQL差

5、如何选择

尽量使用ORM,除了含子查询的复杂语句『不过大流量下的网站最好不要写这种复杂SQL』,当然这也只是一个原则,所以反过来说也可以,不过以下几个场景用ORM的好处是很明显的

  • Model对象不确定的时候,使用多态的方式去处理不同实例的相同操作

  • 语句结构不确定的时候,比如根据不同的情况Where子句不一样的时候,采用if的代码结构去控制ORM方法的使用比拼接SQL语句要清晰的多

  • 设置钩子函数,比如分页里面,拿分页数据同时要count数据,那么就可以在Model里面插入这个算count的钩子函数(包括缓存逻辑)