当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>Java入门

追求“简约不简单”的ORM映射框架

  “简约不简单”,男人味十足的陈道明的精彩的演绎给我们作了非常好的诠释。“简约”也就是要化繁为简、直接明了, 也就是将生活上和设计上多余的东西撇掉,点到即止。“不简单”就是只指“简约”的背后是一些复杂的设计及功能实现。“简约不简单”,是一种兼容并蓄的思想,广泛来说就是记贴近生活、合乎人性,才是设计的最终目的。

  说起持久层框架或方案,最先想到的肯定是Entity Bean,受过Entity Bean折磨的朋友都知道,其非常的不简单的同时,也非常的不简约。不管是CMP还是BMP的Entity Bean,曾经让J2EE用来作显耀资本的Entity Bean今天回过头去看就像一个怪胎,甚至会有一种让人哭笑不得的感觉。EBJ3.0中推出的JPA,终结了“轻量与重量持久之争”的同时,也宣判了Entity Bean的死刑,基于Entity Bean造价昂贵的系统也成了遗留系统。
  轻量级持久化解决方案设想的萌芽、成形、广泛应用到最终到打败Entity Bean的这一过程,给我们揭示了很多现代科学技术发展的客观规律,我认为其中一个规律可以概括为:“简约而不简单”。通过最简约的表达手段达到最好的表达效果一直是各个不同领域的创造者的目的,软件也不例外同,因此“简约主义(英文:minimalism)”应该是我们软件设计的基本思想之一

  相对于Entity Bean,轻量级持久化方案显得就“简约”了许多。不依赖于任何框架的纯POJO,即方便领域建模,也方便单元测试,更方便移植、维护及扩展。然而,在JDK1.5以前,面对轻量级ORM中的那一堆繁杂的配置文件,如何有效管理却是让人非常头痛;尽管一些ORM系统通过引入Jakarta Commons Attributes或类似的思想来实现源码级标签声明持久层对象映射,零乱的标签定义仍然无法从根本上改善映射属性配置信息管理维护的复杂性。

  JDK1.5以后,注解(Annotation)的引入为我们提供了一种非常好的源码级配置处理方式。因此,在各种项目中得到了非常好的引用,使得持久层的方案更加简约。特别是JPA,可算是“简约”持久层的一个里程碑。因此,现在再来像Spring的Rod Johnson大叔前两年那样再来谈怎么灭掉EJB,难免会有点滑稽可笑。

  Hibernate3.2已经实现了JPA,还有很多的持久层ORM框架也将会实现JPA,因此您如果使用这些框架仍然可以在升级版本中享受其一定的简约。然而“简约”是无尽头的,永远无法轻易达到一种完美的境界,JPA也是如此。

  这里使用EasyDBO框架,举一个简单的例子,来演示“简约”追求的过程。
  可以不需要使用配置文件,直接使用Java注解标签,通过下面的方式定义持久层对象:


 @Table(tableName  =   " OrderInfo " )
 public   class  Order  implements  Serializable   {
 @TableField(name  =   " id " )
  private  Number id; // 主键id 
 
 @TableField(name  =   " sn " )
  private  String sn; //  定单编号 
 
 @TableField(name  =   " vdate " )
  private  Date vdate; // 定单日期 
 
 @TableField(name  =   " requireDate " )
  private  Date requireDate; // 交付日期 
 
 @TableField(name  =   " payType " )
  private  String payType; // 支付方式 
 
 @TableField(name  =   " linkMan " )
  private  String linkMan; // 联系人 
 
 @TableField(name  =   " tel " )
  private  String tel; // 电话 
 
 @TableField(name  =   " address " )
  private  String address; // 地址 
 
 @TableField(name  =   " requirement " )
  private  String requirement; // 需求描述 
 
 @TableField(name  =   " remark " )
  private  String remark; // 备注 
 
 @TableField(name  =   " amount " )
  private  BigDecimal amount; // 订单总金额 
 
 @TableField(name  =   " handPerson " )
  private  String handPerson; // 经手人 
 
 @TableField(name  =   " inputUser " )
  private  String inputUser; // 录入人 
 
 @TableField(name  =   " inputTime " )
  private  Date inputTime; // 录入时间 
 
 @TableField(name  =   " opUser " )
  private  String opUser; // 操作人 
 
 @TableField(name  =   " opIntro " )
  private  String opIntro; // 操作简介 
 
 @TableField(name  =   " opTime " )
  private  Date opTime; // 操作时间 
 
 @TableField(name  =   " status " )
  private  Integer status; // 订单状态 
 
 @TableField(name  =   " payment " )
  private  Integer payment; // 支付状态 
 
 @OneToOne(column  =   " customer_id " , type  =  Customer. class )
  private  Customer customer; // 一对一关联,定单对应的客户 
 
 @ManyToOne(column  =   " order_id " , type  =  OrderDetail. class )
  private  Set < OrderDetail >  children  =   new  HashSet < OrderDetail > (); // 一对多关联,定单下面的详细信息 
 
   public  Number getId()   {
   return  id;
 } 
 
   public   void  setId(Number id)   {
   this .id  =  id;
 } 
 
   public  String getAddress()   {
   return  address;
 } 
…省略后面普通的getter及setter

 

 

  由于不再需要使用配置文件,通过源码级的Java注解标签来标识映射关系,确实要简单多了,而且也非常方便开发工具识别。然而,如果写多了,你会发现,那么多重复的标签,而且大多数内容又相同或类似,依靠代码生成工具总不是办法。比如@TableField(name=”XXX”),其中,XXX有80%以上都是属性的字段的名称,因此ORM系统应该要提供这些默认配置。下面是删除掉所有重复、规律一致标签后的持久层对象Order的改进写法:


 @Table(tableName  =   " OrderInfo " )
 public   class  Order  implements  Serializable   {
 @OneToOne(column  =   " customer_id " , type  =  Customer. class )
  private  Customer customer; // 一对一关联,定单对应的客户 
  @ManyToOne(column  =   " order_id " , type  =  OrderDetail. class )
  private  Set < OrderDetail >  children  =   new  HashSet < OrderDetail > (); // 一对多关联,定单下面的详细信息 
 
  private  Number id; // 主键id 
   private  String sn; //  定单编号 
   private  Date vdate; // 定单日期 
   private  Date requireDate; // 交付日期 
   private  String payType; // 支付方式 
   private  String linkMan; // 联系人 
   private  String tel; // 电话 
   private  String address; // 地址 
   private  String requirement; // 需求描述 
   private  String remark; // 备注 
   private  BigDecimal amount; // 订单总金额 
   private  String handPerson; // 经手人 
   private  String inputUser; // 录入人 
   private  Date inputTime; // 录入时间 
   private  String opUser; // 操作人 
   private  String opIntro; // 操作简介 
   private  Date opTime; // 操作时间 
   private  Integer status; // 订单状态 
   private  Integer payment; // 支付状态 
    public  Number getId()   {
   return  id;
 } 
   public   void  setId(Number id)   {
   this .id  =  id;
 } 
…省略后面普通的getter及setter

 
 

  当然,在上面的POJO中,除了一对一、一对多等关联需要进行标注以外,其它的都是使用数据表字段名与对象的属性名相同的映射。追求完美的你还会提出,@OneToOne标签也应该是可省的,另外,表名、多表映射、关联字段等都可以再进一步“简约”,更多复杂(“不简单”)的处理,交由ORM框架来处理。

  简约主义不但是一种文化倾向,是一种时尚潮流,是一种艺术家理想主义的探索,还是一种美学定义或是一种哲学教育,它是一种被建筑师、画家、音乐家、作家在过去几年中不断提及的现象,更应该成为我们软件设计中的一种思想方法及追求的目标。因此,文章结尾忍不住想问一句:今天你“简约”了吗?
  
  鉴于国内大量“春迷”的存在,为了照顾广大“春迷”的情绪,最后补充一段。本文之所以使用EasyDBO作举例,只是出于对国内开源项目的支持。本人也是EasyDBO的主创人员之一,深知这一框架当前还不完善,还存在着这样那样的问题,有很多需要改进的地方。因此,请不要误认为又在炒作什么。如果你真正喜欢技术,喜欢开源的话,就请静下心来,多给我们提一些技术性的建议、不足以及问题,当然更欢迎加入到我们的开发团队中来,前提是改掉“春迷”所具有的恶习。

 (注:本文作者,EasyJF开源团队 大峡,版本归作者所用,转载请保留版权及作者声明!谢谢!)

相关内容
赞助商链接