Username: Password:

Hibernate中any元素的应用体会
来源:linux宝库作者:linux宝库 发布时间:2007-09-30 00:00:00


  Hibernate中any元素的应用体会

  关联(Associations)是Hibernate核心概念之一,比较常用的有:

  many-to-one, one-to-one, one-to-many, many-to-many

  Hibernate还提供了另外一种关联——异类关联(Heterogeneous Associations)

  在Hibernate Reference (cn) 2.1.6中是这样说明的:

  引用:

  6.10. 异类关联(Heterogeneous Associations)

  元素提供真正的异类关联。这些元素和元素工作方式是同样的,他们都应该很少用到。

  下面针对元素,谈一些自己的体会。

  一、什么时候需要元素

  持久类中“一个属性”关联“另外一个指定的持久类”(几乎每个应用都有这种情况),多半会使用many-to-one, one-to-one这样的关联。映射到关系数据库中,也多半使用外键约束。

  可能会碰到有这么一种特别的情况,需要:持久类中“一个属性”关联“另外一些持久类”。

  举个例子:Log类中使用logEntity属性关联一组业务持久类。(也就是说,在Log中记录不同业务类的实例对象)

  假如使用many-to-one,则有很大的限制。首先,需要这些业务类都要继承一个超类,而且在数据库中必须有这个超类对应的表。在Hibernate提供的三种继承映射策略中,只能使用前两种:

  1、“每棵类继承树使用一个表(table per class hierarchy) ”

  2、“每个子类一个表(table per subclass)”

  第1种通常不大合适:任何的业务类映射为一张表,冗余过多,限制也多,增加一个业务类就需要修改表结构,不易扩展。

  第2种的情况是:表的数量=业务表数量 + 一个超类表,子类表通过主键和超类表关联(所以实际上关系模型是一对一关联)。业务表数量比较多的时候,这种结构的性能和灵活性都有问题。

  这时元素就派上用场啦。

  二、元素的应用

  1、类:

  业务类:

  java代码:

  public class BizOne {

  private Long

  id;

  private String

  bizOneDescription;

  //Getters and Setters 省略

  }

  public class BizTwo {

  private Long

  id;

  private String

  bizTwoDescription;

  private Date

  createDate;

  //Getters and Setters 省略

  }

  日志类:

  java代码:

  public class MyLog {

  private Long

  id;

  private Date

  logDate;

  private Object

  logEntity;

  //这就是元素对应的属性。

  //Getters and Setter 省略

  }

  2、hbm.xml 和 表结构:

  这里只给出MyLog的hbm.xml(BizOne, BizTwo很简单,不提了):

  java代码:

  

  

  

  

  


  

  

  

  

  

  

  


  


  


  表结构(MySQL):

  java代码:

  create table MyLog (

  id BIGINT NOT NULL AUTO_INCREMENT,

  logDate datetime,

  entityMetaValue VARCHAR(20),

  entityId BIGINT,

  primary key (id)

  )

  对元素中子元素和属性的理解,能够结合生成的表结构,及其表中的数据(见3):

  name: 是持久类中属性名称。

  meta-type: 是下面meta-value元素中value的类型,如"string","character"等。

  id-type: 是引用类的主键类型。

  meta-value元素中value: 该值将保存到数据库表中,用来标识其后的class,即引用的持久类。请参考下面的数据。

  meta-value元素中class: 引用持久类的类全称。

  第一个column: 保存上面value值的字段。

  第二个column: 保存引用持久类的主键值的字段,他的类型是id-type对应到数据库中的字段类型。

  3、记录日志的方法:

  java代码:

  public MyLog recordLog(Object biz){

  MyLog log = new MyLog();

  log.setLogDate(new Date());

  log.setLogEntity(biz);

  //引用了传递过来的业务对象

  return getLogService().save(log);

  //保存log。我习惯用Spring+Hibernate。

  }

  Hibernate所保存的数据是这样:

  引用:

  --

  ---------------------------------

  ---------------

  --------

  id

  logDate

  entityMetaValue

  entityId

  --

  ---------------------------------

  ---------------

  --------

  1

  2004-11-15 20:48:52.211

  One

  1

  2

  2004-11-15 20:57:25.385

  Two

  2

  3

  2004-11-15 21:48:52.211

  One

  15

  4

  2004-11-15 22:51:15.185

  Two

  26

  5

  2004-11-15 23:27:55.123

  Two

  36

  4、读取Log

  java代码:

  public MyLog readLog(Long id){

  MyLog log = getLogService().getLog(id);

  Object biz = log.getLogEntity();

  //...

  return log;

  }

  用所实现的关联,和等关联的效果是相同的。例如,假如BizOne, BizTwo的lazy="true",则biz是个代理。

  5、BizThree假如增加了一个业务类BizThree,在MyLog.hbm.xml中只需增加一行:

  java代码:

  

  6、限制

  在元素中需要指定id-type,这可能是对所关联类的唯一限制了:所关联的类的主键类型必须相同。

  三、再谈继承映射策略问题

  上面提到了:假如为了让Log能够关联业务类,就需要业务类都要继承同一个超类,是不大合适的。但是,不合适的理由在于这个超类需要在数据库有相应的表。不能说,业务类不能继承一个超类。实际上,很多应用中的业务类都有超类,而且根据情况实现一些接口。此时的继承映射策略是Hibernate Reference中的第三种:每个具体类一个表(table per concrete class)。上面MyLog中的logEntity的类型能够是更有意义的超类,如Entity,当然也能够是接口,不必是Object。这样,即使超类在数据库中没有对应的表,照样能够实现关联。

  四、彩票

  Hibernate Reference中提到元素的地方不是很多,但提到时,总不忘记说“应该很少用到”,“应该在很特别的情况下使用他”。可能从全世界的角度看,使用是低概率事件,但是假如碰到了,就是100%的概率了。因此,当您应用的时候,别忘了购买彩票。因为,和中奖同样的低概率事件——使用——您已碰到了,您的运气就来了,赶快买彩票吧,准能中奖!

喜欢本文,那就收藏到:

    Del.icio.us Google书签 Digg Live Bookmark Technorati Furl Yahoo书签 Facebook 百度搜藏 新浪ViVi 365Key网摘 天极网摘 和讯网摘 博拉网 POCO网摘 添加到饭否 QQ书签 Digbuzz我挖网
相关评论  我也要评论
还没有关于此文章的相关评论!
  • 昵称: (为空则显示guest)
  • 评论分数: ★ ★ ★★★ ★★★★ ★★★★★
  • 评论内容:(不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。
  • 导航
    赞助商
    文章类别
    订阅