scdnzhoulu 2011-02-13
何谓“持久化”
持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。
何谓“持久层”
持久层(PersistenceLayer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。
何谓“对象数据映射(ORM)”
ORM-Object/RelationalMapper,即“对象-关系型数据映射组件”。对于O/R,即Object(对象)和Relational(关系型数据),表示必须同时使用面向对象和关系型数据进行开发。
备注:建模领域中的ORM为Object/RoleModeling(对象角色建模)。另外这里是“O/RMapper”而非“O/RMapping”。相对来讲,O/RMapping描述的是一种设计思想或者实现机制,而O/RMapper指以O/R原理设计的持久化框架(Framework),包括O/R机制还有SQL自生成,事务处理,Cache管理等。
除了ORM技术,还有以下几种持久化技术
主动域对象模式
它是在实现中封装了关系数据模型和数据访问细节的一种形式。在J2EE架构中,EJB组件分为会话EJB和实体EJB。会话EJB通常实现业务逻辑,而实体EJB表示业务实体。实体EJB又分为两种:由EJB本身管理持久化,即BMP(Bean-ManagedPersistence);有EJB容器管理持久化,即CMP(Container-ManagedPersistence)。BMP就是主动域对象模式的一个例子,BMP表示由实体EJB自身管理数据访问细节。
主动域对象本身位于业务逻辑层,因此采用主动域对象模式时,整个应用仍然是三层应用结构,并没有从业务逻辑层分离出独立的持久化层。
JDO模式
JavaDataObjects(JDO)是SUN公司制定的描述对象持久化语义的标准API。严格的说,JDO并不是对象-关系映射接口,因为它支持把对象持久化到任意一种存储系统中,包括关系数据库、面向对象的数据库、基于XML的数据库,以及其他专有存储系统。由于关系数据库是目前最流行的存储系统,许多JDO的实现都包含了对象-关系映射服务。
CMP模式
在J2EE架构中,CMP(Container-ManagedPersistence)表示由EJB容器来管理实体EJB的持久化,EJB容器封装了对象-关系的映射及数据访问细节。CMP和ORM的相似之处在于,两者都提供对象-关系映射服务,都把对象持久化的任务从业务逻辑中分离出来。区别在于CMP负责持久化实体EJB组件,而ORM负责持久化POJO,它是普通的基于JavaBean形式的实体域对象。
一般把基于JavaBean形式的实体域对象称为POJO(PlainOldJavaObject),意为又普通又古老的Java对象的意思。随着各种ORM映射工具的日趋成熟和流行,POJO有重现光彩,它和基于CMP的实体EJB相比,即简单又具有很高的可移植性,因此联合使用ORM映射工具和POJO,已经成为一种越来越受欢迎的且用来取代CMP的持久化方案。POJO的缺点就是无法做远程调用,不支持分布式计算。
为什么要做持久化和ORM设计
在目前的企业应用系统设计中,MVC,即Model(模型)-View(视图)-Control(控制)为主要的系统架构模式。MVC中的Model包含了复杂的业务逻辑和数据逻辑,以及数据存取机制(如JDBC的连接、SQL生成和Statement创建、还有ResultSet结果集的读取等)等。将这些复杂的业务逻辑和数据逻辑分离,以将系统的紧耦合关系转化为松耦合关系(即解耦合),是降低系统耦合度迫切要做的,也是持久化要做的工作。MVC模式实现了架构上将表现层(即View)和数据处理层(即Model)分离的解耦合,而持久化的设计则实现了数据处理层内部的业务逻辑和数据逻辑分离的解耦合。而ORM作为持久化设计中的最重要也最复杂的技术,也是目前业界热点技术。
简单来说,按通常的系统设计,使用JDBC操作数据库,业务处理逻辑和数据存取逻辑是混杂在一起的。
一般基本都是如下几个步骤:
1、建立数据库连接,获得Connection对象。
2、根据用户的输入组装查询SQL语句。
3、根据SQL语句建立Statement对象或者PreparedStatement对象。
4、用Connection对象执行SQL语句,获得结果集ResultSet对象。
5、然后一条一条读取结果集ResultSet对象中的数据。
6、根据读取到的数据,按特定的业务逻辑进行计算。
7、根据计算得到的结果再组装更新SQL语句。
8、再使用Connection对象执行更新SQL语句,以更新数据库中的数据。
7、最后依次关闭各个Statement对象和Connection对象。
由上可看出代码逻辑非常复杂,这还不包括某条语句执行失败的处理逻辑。其中的业务处理逻辑和数据存取逻辑完全混杂在一块。而一个完整的系统要包含成千上万个这样重复的而又混杂的处理过程,假如要对其中某些业务逻辑或者一些相关联的业务流程做修改,要改动的代码量将不可想象。另一方面,假如要换数据库产品或者运行环境也可能是个不可能完成的任务。而用户的运行环境和要求却千差万别,我们不可能为每一个用户每一种运行环境设计一套一样的系统。
所以就要将一样的处理代码即业务逻辑和可能不一样的处理即数据存取逻辑分离开来,另一方面,关系型数据库中的数据基本都是以一行行的数据进行存取的,而程序运行却是一个个对象进行处理,而目前大部分数据库驱动技术(如ADO.NET、JDBC、ODBC等等)均是以行集的结果集一条条进行处理的。所以为解决这一困难,就出现ORM这一个对象和数据之间映射技术。
举例来说,比如要完成一个购物打折促销的程序,用ORM思想将如下实现(引自《深入浅出Hibernate》):
业务逻辑如下:
publicDoublecalcAmount(Stringcustomerid,doubleamount)
{
//根据客户ID获得客户记录
Customercustomer=CustomerManager.getCustomer(custmerid);
//根据客户等级获得打折规则
Promotionpromotion=PromotionManager.getPromotion(customer.getLevel());
//累积客户总消费额,并保存累计结果
customer.setSumAmount(customer.getSumAmount().add(amount);
CustomerManager.save(customer);
//返回打折后的金额
returnamount.multiply(protomtion.getRatio());
}
这样代码就非常清晰了,而且与数据存取逻辑完全分离。设计业务逻辑代码的时候完全不需要考虑数据库JDBC的那些千篇一律的操作,而将它交给CustomerManager和PromotionManager两个类去完成。这就是一个简单的ORM设计,实际的ORM实现框架比这个要复杂的多。
目前有哪些流行的ORM产品
目前众多厂商和开源社区都提供了持久层框架的实现,常见的有
ApacheOJB(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模型逐步确立了在JavaORM架构中领导地位,甚至取代复杂而又繁琐的EJB模型而成为事实上的JavaORM工业标准。而且其中的许多设计均被J2EE标准组织吸纳而成为最新EJB3.0规范的标准,这也是开源项目影响工业领域标准的有力见证。