Hibernate3.0vsRailsActiveRecord

来源:互联网 发布:linux安装多版本jdk 编辑:程序博客网 时间:2024/04/30 06:49
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>

  原文:http://blog.csdn.net//calvinxiu/archive/2005/04/25/361411.aspx

  Rails的出现,良性的冲击了自己目前使用的Spring+Hibernate架构。有冲击是好的,否则EJB2和Struts现在还一统江湖。

  本文主要记述了Hibernate3.0(H3)和RailsActiveRecord(AR)在定义和使用DomainObjectt方面的优劣,更重要是冲击过后,计划如何重构改善自己的框架。

  POJO定义

  1.AR定义POJO的只需这样寥寥几笔

  classCompany

  has_many:clients

  belongs_to:boss

  end

  其中"公司名"之类的属性,已经被AutomateMapping了,而has_many、belongs_to语句清晰的声明了与clients、boss的关联关系。

  2.对比Hibernate2.0时代

  程序员必须同时维护POJO与hbm两个文件事无大小逐一重复声明,而且如果使用XDoclet,更加冗长得要命。此时,ActiveRecord的定义方式简直是生产力大解放,两家的代码行数上有几十倍的差别。

  3.幸亏,Hibernate3.0已经支持Annotation声明。

  终于可以丢弃hbm文件了,同时h3也会拥有表名和列名automapping的智能,就像这样:

  @Entity

  publicclassCompanyimplementsSerializable{

  @Id

  publicLonggetCompanyNo(){returncompanyNo;}

  publicStringgetName(){returnname;}

  @ManyToOne

  @JoinColumn(name=“boss_id”)

  publicBossgetBoss(){returnregionalCenter;}

  @Transient

  StringgetLengthInMeter()

  }

  其中公司名被automatemapping了,@ManyToOne定义了关系,@Transient定义了该属性不需要被持久化。

  4.最后觉得

  对比起来,似乎Hibernate3.0的方式更好,毕竟AR把东西都列名都auto-map得没影了,要自己打开数据库的Schema来看。而且H3可以比AR定义复杂的关系和情况。不过H3的Annotation只出到Beta1,还要赶紧努力。

  DomainModel使用

  首先两者都属于MartinFowler说的DomainModel范畴,不过AR当然就是ActiveRecord模式,而Hibernate属于DataMapper。

  ActiveRecord因为totally只有一个POJO对象,所以几乎强迫性的使用了DDD的模式。

  而DataMapper模式据Martin说为了彻底解耦数据库结构和领域对象,增加了一个EntityManager类(JDO叫PersistenceManager,Hibernate叫Session.TopLink叫UnitOfWork),这便引发了关于DDD(DomainDrivenDevelop)和贫血的POJO,事务脚本式的Service层等无穷争论。

  ActiveRecord的特点:代表着数据库中的一行数据,拥有领域对象的领域属性,领域方法和持久性方法,finder方法被定义为类的静态方法。同时因为Cat继承于ActiveRecord,因此默认具有new,save,find,find_all等方法。

  cat=Cat.find(pkId)

  cat.catch(mouse)

  cat.save

  对于极端OO分子及小白编程主义者来说,上面的代码真是棒极了。

  而Hibernate里面,因为有session,有Manager类,还有service层,甚至还有一个DAO层的存在,组合便变得迷离起来。

  争论的起因很简单,因为领域方法在极端理想的情况下才会只操作自己的属性,比如countTax(),而很多情况下都需要动态的执行find()方法从数据库里再拉些对象参与事务,有很多时候拉的还是别人的对象。因此,怎么组合Service,Manager,DAO变是DDD争论的开始。

  关于DDD的口水已经太多了,自己实际中也还是高级DAO的水平。这里随便一说:

  1.有些极端清廉的做法,每个Manager只负责与自己的POJO相关的动作,把综合的事务都交给Service层,这就是让Martin大发牢骚的复杂service模式。

  其实这是把Manager类重新退化为表入口的模式。既然我们提倡OO,就应该勇敢的进行关联,从来没见过不关联别人的事物。怕的话最多把依赖对象抽象成一个interface。依赖一个很公共的interface比依赖某个具体实现类强。

  2.另一个最普遍的清廉做法,POJO就only拥有自己的领域属性,和领域方法,而没有DAO的句柄。这种模式,即使是很多示范性的著名例子都是这样的。但这显然一厢情愿的认为领域方法就是倒腾领域对象自己的那几个属性和相关对象,其实如前所述,POJO持有DAO的指针是需要的。

  所以POJO应该利用Spring,利用IOC,很优雅的在必要时持有DAO和他的session,很希望有著名例子能够提供这样的示范。

  改进计划

  1.首先是尝试使用Hibernate3.0AnnotationBeta1,去掉hbm文件,并使用她的automapping功能简化配置

  2.使用反射,加强Manager类的父类,拥有一批默认的方法。

  虽然有MDA可以自动在子类生成这些方法,但我认为生成以后还是有维护与代码量的成本,所以即使是CodeGeneration,也应该先使用重用技术把代码减到最少再进行代码生成,不能因为有了CodeGeneration就不注意代码的抽象重用。

  3.研究如何在Spring体系下让POJO优雅的持有DAO句柄,实现真正的DDD编程。

  4.参照Rails,研究如何在父类增加validates_uniqueness_of:subdomain这样的函数。

  5.参照Rails,研究Hibernate3下面对Event的管理和Observer模式的应用。

  最后,TSS上有个HibernatevsRails的文章,是由<HibernateQuickly>的合著者写的。

<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击