一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java的Hibernate框架中的繼承映射學習教程

Java的Hibernate框架中的繼承映射學習教程

2020-05-26 11:58zhang_xinxiu JAVA教程

Hibernate中的映射可以將類與表對應,并利用類的繼承特性,這里我們就來看一下Java的Hibernate框架中的繼承映射學習教程

一、繼承映射
繼承是面向對象很重要的特性,它實現了代碼的服用,在關系模型中同樣也有繼承關系,這種繼承關系其實可以看做是一種枚舉關系,一種類型中可以枚舉出很多子類型,這些子類型和父對象形成了繼承關系,能夠對其進行枚舉的大部分都可以看做是一種繼承映射,所以這種枚舉關系可以看做是繼承映射,例如動物就是一種抽象類,它是其它動物豬、貓等的父類,它們之間就是一種繼承關系,如下圖:

Java的Hibernate框架中的繼承映射學習教程

這種繼承映射在轉化為關系模型后會生成一張表,那么這張表是如何區分這兩種類型的呢?用的是關系字段,需要在表中添加類型字段,使用關鍵字來標明對象的類型。所以上圖中的對象模型對應的表結構如下:

Java的Hibernate框架中的繼承映射學習教程

在生成表結構時,需要添加對應的字段類型,所以需要在映射文件中添加對應的映射鑒別器,這里就需要使用discriminator-value屬性。
1.類文件
類文件中沒有需要注意的地方,在編寫時注意之間的繼承關系即可。
清單一:Animal類代碼,只需要添加基本的屬性。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.src.hibernate;
 
public class Animal {
 
 //id號
 private int id;
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 
 //名稱
 private String name;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 
 //性別
 private boolean sex;
 public boolean isSex() {
 return sex;
 }
 public void setSex(boolean sex) {
 this.sex = sex;
 }
}

清單二:Bird和Pig類,添加基本的屬性,并繼承Animal類。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.src.hibernate;
public class Bird extends Animal {
 
 //高度
 private int height;
 public int getHeight() {
 return height;
 }
 public void setHeight(int height) {
 this.height = height;
 }
 
}
 
package com.src.hibernate;
public class Pig extends Animal {
 
 //重量
 private int weight;
 public int getWeight() {
 return weight;
 }
 public void setWeight(int weight) {
 this.weight = weight;
 }
}

2.映射文件
映射文件中需要添加對應的映射,該模型中只需要添加一個映射文件,因為只生成一張表,在映射文件中添加對應的子類映射,使用<subclass>標簽,標簽中添加鑒別器discriminator-value,該鑒別器屬性指明了在數據庫中寫入數據時指示寫入的是何種類型,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.src.hibernate.Animal" table="t_animal">
 <id name="id">
 <generator class="native"/>
 </id>
 <!-- 加入鑒別標簽,且必須放在id后面 -->
 <discriminator column="type" />
 <property name="name"/>
 <property name="sex" type="boolean"/>
 
 <subclass name="com.src.hibernate.Pig" discriminator-value="P">
 <property name="weight"/>
 </subclass>
 <subclass name="com.src.hibernate.Bird" discriminator-value="B">
 <property name="height"/>
 </subclass>
 </class>
 
</hibernate-mapping>

3.分析結果
生成的MySQL數據庫表中不僅會添加Animal的基本屬性,而且會添加Pig和Bird的屬性,因為在映射文件中使用<subclass>寫出了所添加的屬性,另外還添加了相應的鑒別器屬性,所以在數據庫中會添加對應的鑒別列,生成的表結構如下圖:

Java的Hibernate框架中的繼承映射學習教程

 

二、數據操作

1.寫入數據
在進行數據讀取和寫入操作時需要注意類中的操作使用了

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public void testSave(){
 Session session=null;
 try{
 //創建session對象
 session=HibernateUtils.getSession();
 //開啟事務
 session.beginTransaction();
 
 Pig pig=new Pig();
 pig.setName("小豬豬");
 pig.setSex(true);
 pig.setWeight(200);
 session.save(pig);
 
 Bird bird=new Bird();
 bird.setName("xiaoniaoniao");
 bird.setSex(true);
 bird.setHeight(100);
 session.save(bird);
 
 session.getTransaction().commit();
 }catch(Exception e){
 e.printStackTrace();
 session.getTransaction().rollback();
 }finally{
 HibernateUtils.closeSession(session);
 }
 
}

2.多態查詢--get和hql

基本的查詢方法,只需要使用load和get方法即可,這里重點討論多態查詢。多態查詢是指Hibernate在加載對象時能夠采用instanceof鑒別出其真正的類型的對象即可為多態查詢。
Note:多態查詢不支持延遲加載,也就是說如果使用load方法,需要在映射文件中將延遲加載設置為false。

3.load延遲加載
load支持延遲加載,在加載對象時其實生成的是對象的代理,所以在使用多態查詢時需要在映射文件中將延遲加載設置為false,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.src.hibernate.Animal" table="t_animal" lazy="false">
 <id name="id">
 <generator class="native"/>
 </id>
 <!-- 加入鑒別標簽,且必須放在id后面 -->
 <discriminator column="type" />
 <property name="name"/>
 <property name="sex" type="boolean"/>
 
 <subclass name="com.src.hibernate.Pig" discriminator-value="P">
 <property name="weight"/>
 </subclass>
 <subclass name="com.src.hibernate.Bird" discriminator-value="B">
 <property name="height"/>
 </subclass>
 </class>
</hibernate-mapping>

load加載方法,使用load加載該示例中支持多態查詢,在配置文件中將延遲加載設置為false,所以這里使用load方法能夠加載獲得相應的對象類。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void testLoad(){
 Session session=null;
 try{
 session=HibernateUtils.getSession();
 session.beginTransaction();
 
 Animal ani=(Animal)session.load(Animal.class,1);
 System.out.println(ani.getName());
 //因為load默認支持lazy,所以我們看到的是Animal的代理
 //所以采用了instanceof無法鑒別出真正的類型Pig
 //所以load在此情況下是不支持多態查詢的
 if(ani instanceof Pig){
 System.out.println("我是小豬豬!");
 }else{
 System.out.println("我不是小豬豬!");
 }
 session.getTransaction().commit();
 }catch(Exception e){
 e.printStackTrace();
 session.getTransaction().rollback();
 }finally{
 HibernateUtils.closeSession(session);
 }
}

4.hql查詢
hql支持多態查詢,這主要由于查詢出的是一個真正的對象,并不會返回一個代理,所以hql支持多態查詢,另外在查詢時需要注意查詢語句中不要使用表名,而是要使用類名稱,Hibernate會根據類名稱將其映射為對應的表名稱,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public void testLoad5(){
 Session session=null;
 try{
 session=HibernateUtils.getSession();
 session.beginTransaction();
 
 List<Animal> list=session.createQuery("from Animal").list();
 for(Iterator iter=list.iterator();iter.hasNext();){
 Animal a=(Animal)iter.next();
 if(a instanceof Pig){
 System.out.println("我是小豬豬!");
 }else{
 System.out.println("我不是小豬豬!");
 }
 }
 session.getTransaction().commit();
 }catch(Exception e){
 e.printStackTrace();
 session.getTransaction().rollback();
 }finally{
 HibernateUtils.closeSession(session);
 }
}

查詢結果:

?
1
2
3
4
5
Hibernate: select animal0_.id as id0_, animal0_.name as name0_, animal0_.sex as sex0_, animal0_.weight as weight0_, animal0_.height as height0_, animal0_.type as type0_ from t_animal animal0_
我是小豬豬!
我不是小豬豬!
我是小豬豬!
我不是小豬豬!

三、繼承映射三種策略
1. 每個類分層結構一張表(Table per class hierarchy)

假設我們有接口Payment和它的幾個實現類: CreditCardPayment, CashPayment, 和ChequePayment。則“每個類分層結構一張表”(Table per class hierarchy)的映射代碼如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<class name="Payment" table="PAYMENT">
 <id name="id" type="long" column="PAYMENT_ID">
 <generator class="native"/>
 </id>
 <discriminator column="PAYMENT_TYPE" type="string"/>
 <property name="amount" column="AMOUNT"/>
 ...
 <subclass name="CreditCardPayment" discriminator-value="CREDIT">
 <property name="creditCardType" column="CCTYPE"/>
 ...
 </subclass>
 <subclass name="CashPayment" discriminator-value="CASH">
 ...
 </subclass>
 <subclass name="ChequePayment" discriminator-value="CHEQUE">
 ...
 </subclass>
</class>

采用這種策略只需要一張表即可。它有一個很大的限制:要求那些由子類定義的字段, 如CCTYPE,不能有非空(NOT NULL)約束。

2. 每個子類一張表(Table per subclass)

對于上例中的幾個類而言,采用“每個子類一張表”的映射策略,代碼如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<class name="Payment" table="PAYMENT">
 <id name="id" type="long" column="PAYMENT_ID">
 <generator class="native"/>
 </id>
 <property name="amount" column="AMOUNT"/>
 ...
 <joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
 <key column="PAYMENT_ID"/>
 ...
 </joined-subclass>
 <joined-subclass name="CashPayment" table="CASH_PAYMENT">
 <key column="PAYMENT_ID"/>
 <property name="creditCardType" column="CCTYPE"/>
 ...
 </joined-subclass>
 <joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
 <key column="PAYMENT_ID"/>
 ...
 </joined-subclass>
</class>

需要四張表。三個子類表通過主鍵關聯到超類表(因而關系模型實際上是一對一關聯)。

3. 每個子類一張表(Table per subclass),使用辨別標志(Discriminator)

注意,對“每個子類一張表”的映射策略,Hibernate的實現不需要辨別字段,而其他 的對象/關系映射工具使用了一種不同于Hibernate的實現方法,該方法要求在超類 表中有一個類型辨別字段(type discriminator column)。Hibernate采用的方法更 難實現,但從關系(數據庫)這點上來看,按理說它更正確。若你愿意使用帶有辨別字 段的“每個子類一張表”的策略,你可以結合使用<subclass> 與<join>,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<class name="Payment" table="PAYMENT">
 <id name="id" type="long" column="PAYMENT_ID">
 <generator class="native"/>
 </id>
 <discriminator column="PAYMENT_TYPE" type="string"/>
 <property name="amount" column="AMOUNT"/>
 ...
 <subclass name="CreditCardPayment" discriminator-value="CREDIT">
 <join table="CREDIT_PAYMENT">
 <property name="creditCardType" column="CCTYPE"/>
 ...
 </join>
 </subclass>
 <subclass name="CashPayment" discriminator-value="CASH">
 <join table="CASH_PAYMENT">
 ...
 </join>
 </subclass>
 <subclass name="ChequePayment" discriminator-value="CHEQUE">
 <join table="CHEQUE_PAYMENT" fetch="select">
 ...
 </join>
 </subclass>
</class>

可選的聲明fetch="select",是用來告訴Hibernate,在查詢超類時, 不要使用外部連接(outer join)來抓取子類ChequePayment的數據。

延伸 · 閱讀

精彩推薦
  • JAVA教程Java中接口和抽象類的區別與相同之處

    Java中接口和抽象類的區別與相同之處

    這篇文章主要介紹了Java中接口和抽象類的區別與相同之處,本文講解了抽象類的概念、接口的概念、接口和抽象類的區別與聯系等內容,需要的朋友可以參考...

    junjie2412019-12-20
  • JAVA教程Java命名規則詳細總結

    Java命名規則詳細總結

    Class名應是首字母大寫的名詞。命名時應該使其簡潔而又具有描述性。異常類的命名,應以Exception結尾。Interface的命名規則與Class相同 ...

    java技術網3952019-10-17
  • JAVA教程舉例講解Java的Jackson庫中ObjectMapper類的使用

    舉例講解Java的Jackson庫中ObjectMapper類的使用

    這篇文章主要介紹了舉例講解Java的Jackson庫中ObjectMapper類的使用,Jackson庫通常被用來實現Java的對象和JSON之間的轉換功能,需要的朋友可以參考下 ...

    goldensun3422020-03-22
  • JAVA教程學習Java多線程之同步

    學習Java多線程之同步

    這篇文章主要為大家詳細介紹了Java多線程之同步,感興趣的小伙伴們可以參考一下 ...

    劉望舒2342020-04-06
  • JAVA教程Java開發環境配置方法

    Java開發環境配置方法

    這篇文章主要介紹了并不是每一臺計算機都可以運行Java程序,要運行Java程序,計算機必須學習搭建Java開發環境,需要的朋友可以參考下 ...

    mrr2112019-12-28
  • JAVA教程Java嵌套類和內部類詳解

    Java嵌套類和內部類詳解

    這篇文章主要介紹了Java嵌套類和內部類詳解,本文講解了什么是嵌套類及內部類、靜態嵌套類、在外部類中定義內部類、在方法中定義內部類、匿名內部類...

    junjie1622019-12-17
  • JAVA教程Java中使用異或運算符實現加密字符串

    Java中使用異或運算符實現加密字符串

    這篇文章主要介紹了Java中使用異或運算符實現加密字符串,本文直接給出實現代碼,以及運算結果加密實例,需要的朋友可以參考下 ...

    junjie3302019-12-23
  • JAVA教程Java 批量刪除html中注釋內容的方法

    Java 批量刪除html中注釋內容的方法

    最近項目中有一個功能需要讀取外部html文本文件。但是有的html文件里面有大量的注釋,需要刪除其中的注釋在存儲 ...

    java教程網1532019-11-17
主站蜘蛛池模板: 婷婷色在线观看 | 欧美成人香蕉在线观看 | 好男人资源免费播放在线观看 | 香蕉eeww99国产精选播放 | 成人毛片1024你懂的 | 国产成人在线小视频 | 亚洲人成网站在线观看播放青青 | 亚洲 欧美 国产 在线观看 | 午夜精品久久久久久久99蜜桃 | 国内永久第一免费福利视频 | 免费高清www动漫视频播放器 | yellow视频免费观看播放 | 三级小说网站 | 日本免费三区 | 别停好爽好深好大好舒服视频 | 女同志freelesvoices| 国产精品久久久久久久久久久久 | 久久成人a毛片免费观看网站 | 成人欧美一区在线视频在线观看 | 欧美人与禽杂交大片 | 国产二区视频在线观看 | 国产精品成人va在线观看 | 亚洲精品网址 | 出轨同学会2在线观看 | 4hc44四虎永久地址链接 | 99精品国产久热在线观看66 | 久久综合中文字幕佐佐木希 | 波多野结衣52部合集在线观看 | 美女毛片视频 | 日本一区二区不卡久久入口 | 国产精品51麻豆cm传媒 | 国产伦精品一区二区三区免费观看 | 纲手被强喷水羞羞漫画 | 99精品视频在线观看免费播放 | 国产精品密播放国产免费看 | 乖女的嫩奶水h文孕妇 | juy799大岛优香在线观看 | 亚洲精品第五页 | 皇上好大好硬好涨好深好爽 | 日韩亚洲国产激情在线观看 | 羞羞漫画免费漫画页面在线看漫画秋蝉 |