关于持久化

来源:互联网 发布:手机游戏交易平台源码 编辑:程序博客网 时间:2024/04/29 06:06

关于“持久化”
J2EE程序访问数据库,这是一个无法避免的问题(否则也不算是J2EE了)。要将数据持久化到数据库,解决数据库中的规范数据和OO程序之间的交互是一个技巧性的问题,而O/R Mapping则为此提供了一种不错的解决方案。

关于“对象关系映射(O/R Mapping)”
这是当今最流行一种数据库持久化方案(另一种则是JDO,它基于字节码增强来实现持久化),如Hibernate,iBATIS。
当我们从数据库中取出一条记录时,我们通常将其映射到持久化的java对象,即所谓只含getter和setter方法的类(这种没有任何行为的类被证明并不是十分正确,在类中恰当的提供某些行为或业务逻辑可以获得更好的效果)中,也称为领域模型。这样业务逻辑就可以表现为这些对象之间的交互,而不是直接操纵数据库里的字段。
如何将数据库映射到领域模型呢?

关于“DAO”
DAO(Data Access Object)数据访问对象,作为很早就出现的一种模式,至今仍然非常有用。他的作用是全权承担业务逻辑的持久化操作。

java 代码
  1. public class BusinessObject extends BusinessHomeAction{   
  2.     ...   
  3.     public void insert(){   
  4.         try{   
  5.             ...   
  6.             BusinessObjectDAO businessObjectDAO = new BusinessObjectDAO();   
  7.             int count = businessObjectDAO.insert(businessObjectModel);   
  8.             ...   
  9.         }catch(SQLException se){   
  10.             ...   
  11.         }catch(Exception e){   
  12.             ...   
  13.         }finnaly{   
  14.             ...   
  15.         }   
  16.     }   
  17.     ...   
  18. }   
  19. public class BusinessObjectDAO extends BusinessHomeDAO{   
  20.     ...   
  21.     public BusinessObjectModel findByPrimaryKey(BusinessObjectModel businessObjectModel)throws SQLException, Exception{...};   
  22.     public int insert(BusinessObjectModel businessObjectModel)throws SQLException, Exception{...};   
  23.     public int update(BusinessObjectModel businessObjectModel)throws SQLException, Exception{...};   
  24.     public int delete(BusinessObjectModel businessObjectModel)throws SQLException, Exception{...};   
  25.     ...   
  26. }   
  27. public class BusinessObjectModel extends BusinessHomeModel{...}  

这是一种简单DAO实现。也就是说,每一个领域模型就对应一个DAO操作(或者说每一个表就对应一个可操纵数据库的DAO对象)。DAO模式好处在于,将JDBC从业务逻辑中隐藏起来,业务逻辑不再关心象JDBC这样的底层操作,全权将其交给DAO处理,你可以很清楚的看到那些持久化对象被取出创建或者修改。而当你需要更改数据库或者栏位的时候,你只需要改掉DAO就好,而不需要重写你的业务逻辑。
然而,这样的DAO实现其本质就是在JDBC之上实现了一层薄薄的封装,对于现在复杂而厚重的商业逻辑持久化来说,它看起来确实显得“单薄”了些。
- 这是一种基于SQL组装的模型,但它不是自动的,我们必须自己去实现(事实上现在通常是使用代码自动生称的方式,即你可能要特制你的代码生成器,但对于业务逻辑中一些特殊的持久化操作,你仍然需要自己手动去实现SQL组装)。
- 这样模型对于多表操作来说也是个问题。MODEL和DAO是一一对应的结果,使得将多个MODEL进行联合操作时,你将需要自己去实现对应的持久化逻辑,而怎么实现却是个问题(通常的实现就是选择某一个相关的DAO,直接在它后面追加一个多表操作的方法,即直接使用SQL语句,虽然这样看起来并不漂亮,但无疑它做起来是最简单的)。
基于DAO这种简单的实现依然有很多问题,“透明持久化”概念提供了更优雅的解决方案。

关于“透明持久化”
Transparent Persistence“透明持久化”,
- 它是实现DAO的一种更好的方式(不要将其和上面谈到的那个并不漂亮的DAO实现搞混了)
- 它通常是由框架来实现,而不是由应用本身来关心。它能完全剥离业务的持久化操作,仅仅只需提供一个接口供业务逻辑调用(如Hibernate的Session,JDO的PersistenceManger——JDO并不是基于O/R映射,而是基于字节码增强来实现透明持久化的,iBATIS的SqlMap对象等)。它可能还有自己特殊的语意(如Hibernate的HQL,因为它必须自己实现真正的SQL,提供的HQL可以简化这一过程,同时也简化了业务逻辑持久化时的工作量)。
- 它可以自动侦测所取出的对象的修改(当然,同时应该有提供缓存),并在事务提交时自动将修改后的状态持久化到数据库。
- 它很复杂^-^
虽然实现“透明持久化”方案非常复杂,但我们不需要重新发明轮子,多数情况下,Hibernate,iBATIS,JDO实现已经完全可以满足我们的持久化需求。

关于Hibernate,iBATIS和JDO
Hibernate,iBATIS都是基于O/R映射的,但两者却非常的不同。
iBATIS是SQL的映射,其设计理念为:将SQL语句在XML中定义,并预留占位符(可以指定参数的SQL类型和其他细节)。在执行时,占位符被指定的参数值所取代,参数来至参数映射表、JAVABEAN属性或者搜简单的参数对象。在执行SQL查询时,结果字段将被映射到对象,映射的方式与参数映射是一样的。
而Hibernate则提供了更完善的透明持久化。它为应用程序追加了O/R映射的语意——HQL。HQL查询语言让开发者可以在领域对象的层面来利用SQL的强大功能(即在一定程度是你不在需要自己组装SQL,或者说HQL让组装变得更简单了,而且也不再需要象上面那样,在大量的DAO面前不得不让特定的程序来生成笨重的代码)。
JDO是一组规范,并定义了一系列API,它是除O/R映射以外,用另一种——基于字节码增强的——方式来实现透明持久化的。所谓的字节码增强,是指在做业务动作时,被增强的持久化对象实例如果被修改(即数据的变动通过字节码的变动而被侦测),就会通知JDO的状态管理器,从而做出相应的insert、update或delete动作持久化到数据库。
但是,最终,这些透明持久化方案还得和我们自己的DAO策略集合起来。

持久化的最终结果是要将数据存入数据库中,DAO模式提供了一种更优雅的持久化解决方案(比起业务代码直接使用JDBC来说)。而如何实现DAO是一个重要的问题。DAO模式的最终目的,是为了将“与持久化相关的代码”从业务逻辑中分离出来。所以,如果是自己使用JDBC,做一个DAO——即使是很薄的那种——也是很有必要的,如同上面提到的那个例子。但既然有了Hibernate,iBATIS和JDO等等这样一些优秀的“透明持久化”方案,自己再去发明轮子可算不上明智。在实现DAO时,如果用到了这些开源方案,针对不同的方案实现自己不同的DAO,仍然是个好主意(如当使用Hibernate的时将其封装到自己的DAO里)。

注:以上这些都是已有的概念,我只是将其规整了下并加入了一点自己的理解。如有不对的地方,请不吝指教,十分感谢!

原贴地址:http://www.iteye.com/topic/68651

0 0
原创粉丝点击