数据库的ORM映射框架

转帖|其它|编辑:郝浩|2008-11-19 10:40:51.000|阅读 1060 次

概述:数据库的ORM映射框架

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

  说起持久层框架或方案,最先想到的肯定是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 > (); // 一对多关联,定单下面的详细信息[SPAN]

    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框架来处理。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:IT专家网论坛

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP