Object Relational Mapping-ORM

it2022-05-09  34

     对象关系映射Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 这也同时暗示者额外的执行开销;然而,如果ORM作为一种中间件实现,则会有很多机会做优化,而这些在手写的持久层并不存在。 更重要的是用于控制转换的元数据需要提供和管理;但是同样,这些花费要比维护手写的方案要少;而且就算是遵守ODMG规范的对象数据库依然需要级别的元数据。

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

      面向对象是从软件工程基本原则(如耦合、聚合、封装)的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论存在显著的区别。为了解决这个不匹配的现象,对象关系映射技术应运而生。

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

      当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。   如果打开你最近的程序,看看DAL代码,你肯定会看到很多近似的通用的模式。我们以保存对象的方法为例,你传入一个对象,为SqlCommand对象添加SqlParameter,把所有属性和对象对应,设置SqlCommand的CommandText属性为存储过程,然后运行SqlCommand。对于每个对象都要重复的写这些代码。 比如,按通常的系统设计,使用 JDBC 操作数据库,业务处理逻辑和数据存取逻辑是混杂在一起的。一般基本都是如下几个步骤:1、建立数据库连接,获得 Connection 对象。2、根据用户的输入组装查询 SQL 语句。3、根据 SQL 语句建立 Statement 对象 或者 PreparedStatement 对象。4、用 Connection 对象执行 SQL语句,获得结果集 ResultSet 对象。5、然后一条一条读取结果集 ResultSet 对象中的数据。6、根据读取到的数据,按特定的业务逻辑进行计算。7、根据计算得到的结果再组装更新 SQL 语句。8、再使用 Connection 对象执行更新 SQL 语句,以更新数据库中的数据。7、最后依次关闭各个 Statement 对象和 Connection 对象。

     由上可看出代码逻辑非常复杂,这还不包括某条语句执行失败的处理逻辑(try{..}catch(){..})。其中的业务处理逻辑和数据存取逻辑完全混杂在一块。而一个完整的系统要包含成千上万个这样重复的而又混杂的处理过程,假如要对其中某些业务逻辑或者一些相关联的业务流程做修改,要改动的代码量将不可想象。另一方面,假如要换数据库产品或者运行环境,也可能是个不可能完成的任务。而用户的运行环境和要求却千差万别,我们不可能为每一个用户每一种运行环境设计一套一样的系统。    所以就要将一样的处理代码即业务逻辑和可能不一样的处理即数据存取逻辑分离开来,另一方面,关系型数据库中的数据基本都是以一行行的数据进行存取的,而程序运行却是一个个对象进行处理,而目前大部分数据库驱动技术(如ADO.NET、JDBC、ODBC等等)均是以行集的结果集一条条进行处理的。所以为解决这一困难,就出现 ORM 这一个对象和数据之间映射技术

    举例来说,比如要完成一个购物打折促销的程序,用 ORM 思想将如下实现(引自《深入浅出Hibernate》):业务逻辑如下:

public Double calcAmount(String customerid, double amount) ... { // 根据客户ID获得客户记录 Customer customer = CustomerManager.getCustomer(custmerid); // 根据客户等级获得打折规则 Promotion promotion = PromotionManager.getPromotion(customer.getLevel()); // 累积客户总消费额,并保存累计结果 customer.setSumAmount(customer.getSumAmount().add(amount); CustomerManager.save(customer); // 返回打折后的金额 return amount.multiply(protomtion.getRatio()); }

    这样代码就非常清晰了,而且与数据存取逻辑完全分离。设计业务逻辑代码的时候完全不需要考虑数据库JDBC的那些千篇一律的操作,而将它交给 CustomerManager 和 PromotionManager 两个类去完成。这就是一个简单的 ORM 设计,实际的 ORM 实现框架比这个要复杂的多。

  实质上,一个O/R Mapping会为你生成DAL。与其自己写DAL代码,不如用O/R Mapping。你用O/R Mapping保存,删除,读取对象,O/R Mapping负责生成SQL,你只需要关心对象就好。

     当然,使用ORM也有一些缺点,比如会牺牲程序的执行效率和会固定思维模式。这里就不描述了!     

参考资料:http://www.blogjava.net/fyz210/archive/2007/05/22/119098.html

          http://www.cnblogs.com/tonybinlj/archive/2008/01/10/1032728.html

转载于:https://www.cnblogs.com/lzm525/archive/2009/03/03/1402626.html

相关资源:数据结构—成绩单生成器

最新回复(0)