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

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

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
主站蜘蛛池模板: 99精品国产在现线免费 | 国产精品调教 | 亚州性夜夜射在线观看 | 四虎成人影院网址 | 热久久天天拍天天拍热久久2018 | yellow片在线观看 | 男人女人性生活视频 | 国产51社区精品视频资源 | 国产传媒天美果冻 | 免费高清视频日本 | 无限好资源第一片免费韩国 | 俄罗斯13一14处出血视频在线 | 四虎四虎| 好爽视频 | 久久精品人人做人人爽97 | 99国产小视频 | 美女被网站 | 亚洲123区 | 久青草国产在线观看视频 | 深夜激情网站 | 国产第9页 | 亚洲国产第一区二区三区 | 18性夜影院午夜寂寞影院免费 | 99热久久这里只有精品6国产网 | 亚洲咪咪| avav男人天堂 | 99视频有精品视频免费观看 | 亚洲激情视频在线 | 大杳蕉在线影院在线播放 | 国内久久久 | 91嫩草私人成人亚洲影院 | 美女林柏欣21p人体之仓之梦 | 日韩欧美推理片免费看完整版 | 日韩免费视频播放 | 撕开老师的丝袜白丝扒开粉嫩的小 | 久久婷婷五月免费综合色啪 | 四虎永久免费地址在线观看 | 成人精品亚洲人成在线 | 日麻逼| 91寡妇天天综合久久影院 | 亚洲人成在线观看一区二区 |