国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Hibernate中any元素的應(yīng)用體會

2019-11-18 12:57:41
字體:
供稿:網(wǎng)友

  Hibernate中any元素的應(yīng)用體會
  
  關(guān)聯(lián)(Associations)是Hibernate核心概念之一,比較常用的有:
  
  many-to-one, one-to-one, one-to-many, many-to-many
  
  Hibernate還提供了另外一種關(guān)聯(lián)——異類關(guān)聯(lián)(Heterogeneous Associations)
  
  在Hibernate Reference (cn) 2.1.6中是這樣說明的:
  
  引用:
  
  6.10. 異類關(guān)聯(lián)(Heterogeneous Associations)
  
  <many-to-any>和<index-many-to-any>元素提供真正的異類關(guān)聯(lián)。這些元素和<any>元素工作方式是同樣的,他們都應(yīng)該很少用到。
  
  下面針對<any>元素,談一些自己的體會。
  
  一、什么時候需要<any>元素
  
  持久類中“一個屬性”關(guān)聯(lián)“另外一個指定的持久類”(幾乎每個應(yīng)用都有這種情況),多半會使用many-to-one, one-to-one這樣的關(guān)聯(lián)。映射到關(guān)系數(shù)據(jù)庫中,也多半使用外鍵約束。
  
  可能會碰到有這么一種非凡的情況,需要:持久類中“一個屬性”關(guān)聯(lián)“另外一些持久類”。
  
  舉個例子:Log類中使用logEntity屬性關(guān)聯(lián)一組業(yè)務(wù)持久類。(也就是說,在Log中記錄不同業(yè)務(wù)類的實例對象)
  
  假如使用many-to-one,則有很大的限制。首先,需要這些業(yè)務(wù)類都要繼續(xù)一個超類,而且在數(shù)據(jù)庫中必須有這個超類對應(yīng)的表。在Hibernate提供的三種繼續(xù)映射策略中,只能使用前兩種:
  
  1、“每棵類繼續(xù)樹使用一個表(table per class hierarchy) ”
  
  2、“每個子類一個表(table per subclass)”
  
  第1種通常不大合適:所有的業(yè)務(wù)類映射為一張表,冗余過多,限制也多,增加一個業(yè)務(wù)類就需要修改表結(jié)構(gòu),不易擴(kuò)展。
  
  第2種的情況是:表的數(shù)量=業(yè)務(wù)表數(shù)量 + 一個超類表,子類表通過主鍵和超類表關(guān)聯(lián)(所以實際上關(guān)系模型是一對一關(guān)聯(lián))。業(yè)務(wù)表數(shù)量比較多的時候,這種結(jié)構(gòu)的性能和靈活性都有問題。
  
  這時<any>元素就派上用場啦。
  
  二、<any>元素的應(yīng)用
  
  1、類:
  
  業(yè)務(wù)類:
  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;    //這就是<any>元素對應(yīng)的屬性。
  //Getters and Setter 省略
  }
  
  2、hbm.xml 和 表結(jié)構(gòu):
  
  這里只給出MyLog的hbm.xml(BizOne, BizTwo很簡單,不提了):
  
  java代碼:
  
  <hibernate-mapping>
  <class name="com.test.entity.MyLog" table="MyLog">
  <id name="id" column="id">
  <generator class="native"/>
  </id>
  <property name="logDate"/>
  <any name="logEntity" meta-type="string" id-type="long">
  <meta-value value="One" class="com.test.entity.BizOne"/>
  <meta-value value="Two" class="com.test.entity.BizTwo"/>
  <column name="entityMetaValue" length="20" />
  <column name="entityId"/>
  </any>
  </class>
  </hibernate-mapping>
  
  表結(jié)構(gòu)(MySQL):
  java代碼:
  
  create table MyLog (
  id BIGINT NOT NULL AUTO_INCREMENT,
  logDate datetime,
  entityMetaValue VARCHAR(20),
  entityId BIGINT,
  primary key (id)
  )
  
  對<any>元素中子元素和屬性的理解,可以結(jié)合生成的表結(jié)構(gòu),及其表中的數(shù)據(jù)(見3):
  
  name: 是持久類中屬性名稱。
  meta-type: 是下面meta-value元素中value的類型,如"string","character"等。
  id-type: 是引用類的主鍵類型。
  meta-value元素中value: 該值將保存到數(shù)據(jù)庫表中,用來標(biāo)識其后的class,即引用的持久類。請參考下面的數(shù)據(jù)。
  meta-value元素中class: 引用持久類的類全稱。
  
  第一個column: 保存上面value值的字段。
  
  第二個column: 保存引用持久類的主鍵值的字段,它的類型是id-type對應(yīng)到數(shù)據(jù)庫中的字段類型。
  
  3、記錄日志的方法:
  
  java代碼:
  
  public MyLog recordLog(Object biz){
  MyLog log = new MyLog();
  log.setLogDate(new Date());
  log.setLogEntity(biz);    //引用了傳遞過來的業(yè)務(wù)對象
  
  return getLogService().save(log);    //保存log。我習(xí)慣用Spring+Hibernate。
  }
  
  Hibernate所保存的數(shù)據(jù)是這樣:
  
  引用:
  
  --  ---------------------------------  ---------------   --------
  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;
  }
  
  用<any>所實現(xiàn)的關(guān)聯(lián),與<many-to-one>等關(guān)聯(lián)的效果是相同的。例如,假如BizOne, BizTwo的lazy="true",則biz是個代理。
  
  5、BizThree假如增加了一個業(yè)務(wù)類BizThree,在MyLog.hbm.xml中只需增加一行:
  
  java代碼:
  
  <meta-value value="Three" class="com.test.entity.BizThree"/>
  
  6、限制
  
  在<any>元素中需要指定id-type,這可能是<any>對所關(guān)聯(lián)類的唯一限制了:所關(guān)聯(lián)的類的主鍵類型必須相同。
  
  三、再談繼續(xù)映射策略問題
  
  上面提到了:假如為了讓Log能夠關(guān)聯(lián)業(yè)務(wù)類,就要求業(yè)務(wù)類都要繼續(xù)同一個超類,是不大合適的。不過,不合適的理由在于這個超類需要在數(shù)據(jù)庫有相應(yīng)的表。不能說,業(yè)務(wù)類不能繼續(xù)一個超類。實際上,很多應(yīng)用中的業(yè)務(wù)類都有超類,而且根據(jù)情況實現(xiàn)一些接口。此時的繼續(xù)映射策略是Hibernate Reference中的第三種:每個具體類一個表(table per concrete class)。上面MyLog中的logEntity的類型可以是更有意義的超類,如Entity,當(dāng)然也可以是接口,不必是Object。這樣,即使超類在數(shù)據(jù)庫中沒有對應(yīng)的表,照樣可以實現(xiàn)關(guān)聯(lián)。
  
  四、彩票
  
  Hibernate Reference中提到<any>元素的地方不是很多,但提到時,總不忘記說“應(yīng)該很少用到”,“應(yīng)該在非常非凡的情況下使用它”。可能從全世界的角度看,使用<any>是低概率事件,但是假如碰到了,就是100%的概率了。因此,當(dāng)你應(yīng)用<any>的時候,別忘了購買彩票。因為,與中獎同樣的低概率事件——使用<any>——你已經(jīng)碰到了,你的運(yùn)氣就來了,趕緊買彩票吧,準(zhǔn)能中獎!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 白沙| 明光市| 固始县| 铜川市| 达拉特旗| 隆林| 临武县| 柞水县| 鄂州市| 房产| 延庆县| 大姚县| 叶城县| 苗栗市| 绿春县| 凌源市| 江孜县| 许昌县| 兴和县| 宾阳县| 琼中| 肃北| 聂荣县| 乌鲁木齐县| 台北市| 凌海市| 石阡县| 故城县| 南开区| 达拉特旗| 汽车| 南雄市| 札达县| 酒泉市| 元朗区| 宜兴市| 兴宁市| 平果县| 西平县| 宝丰县| 宝丰县|