Hibernate繼承類的實現


版權聲明:本文為博主原創文章,如需轉載請標注轉載地址。

博客地址:http://www.cnblogs.com/caoyc/p/5603724.html 

  對於繼承關系類的映射。比如在論壇中文章(Ariticla)有主題類型(Topic),有回復類型(Reply)。其中Topic都id、title、context、postDate、type(類型:如普通、精華、置頂......),而Replay有id,title,context,postDate,floor(樓層)。針對這樣的情況,Topic和Replay都有共同的屬性,那么就可以提取出一個抽象類Ariticla,並給Aritcla添加共同屬性id,title,context,postDate。然后讓Topic和Reply繼承Aritcla,然后各自在指定各自的屬性。如圖:

  

 

繼承類三種設計方式

第一種:subclass

  這種類型的特點,可以使用一張表來存儲所有數據。我們需要在數據庫表設計的時候增加一列用於判斷該條記錄的類型

  Sql數據表結構

 

 

  代碼實現:

  Article.java

 1 package com.myproc.domain;
 2 
 3 import java.util.Date;
 4 
 5  public class Article {
 6     private Integer id;  
 7     private String title;    //標題
 8     private String context;  //內容
 9     private Date postDate;   //提交日期
10     public Integer getId() {
11         return id;
12     }
13     public void setId(Integer id) {
14         this.id = id;
15     }
16     public String getTitle() {
17         return title;
18     }
19     public void setTitle(String title) {
20         this.title = title;
21     }
22     public String getContext() {
23         return context;
24     }
25     public void setContext(String context) {
26         this.context = context;
27     }
28     public Date getPostDate() {
29         return postDate;
30     }
31     public void setPostDate(Date postDate) {
32         this.postDate = postDate;
33     }    
34 }

  Topic.java

 1 package com.myproc.domain;
 2 
 3 public class Topic extends Article {
 4     private int type;  //類型:精華、置頂、推薦......
 5 
 6     public int getType() {
 7         return type;
 8     }
 9 
10     public void setType(int type) {
11         this.type = type;
12     }
13     
14 }

  Reply.java

 1 package com.myproc.domain;
 2 
 3 public class Reply extends Article {
 4     private int floor;  //樓層
 5 
 6     public int getFloor() {
 7         return floor;
 8     }
 9 
10     public void setFloor(int floor) {
11         this.floor = floor;
12     }
13     
14 }

  Article.hbm.xml

 1 <?xml version="1.0"?>
 2 
 3 <!DOCTYPE hibernate-mapping PUBLIC
 4         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 5         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 6 <hibernate-mapping package="com.myproc.domain">
 7     <!--discriminator-value:鑒別器的值,如果不指定則為類的全限名(含包) -->
 8     <class name="Article" table="t_article" discriminator-value="A">
 9         <id name="id" column="Id" type="integer">
10             <generator class="native"></generator>
11         </id>
12         <!-- 設置鑒別器,column:在數據庫中的列。根據該列的值判斷是什么類型 -->
13         <discriminator column="class_" type="string"></discriminator>
14         <property name="title"  type="string"></property>
15         <property name="context" type="text" length="1000"></property>
16         <property name="postDate" type="timestamp"></property>
17         
18         <!-- 子類 -->
19         <subclass name="Topic" discriminator-value="T">
20             <!-- 子類屬性 -->
21             <property name="type" type="int"></property>
22         </subclass>
23         
24         <subclass name="Reply" discriminator-value="R">
25             <property name="floor"></property>
26         </subclass>
27     </class>
28 </hibernate-mapping>

  這里主要知識點:

  a、subclass:子類的指定

  b、discriminator:鑒別器的設置

 

  測試代碼:

 1 package com.myproc.test;
 2 
 3 import java.util.Date;
 4 
 5 import org.hibernate.Session;
 6 import org.hibernate.SessionFactory;
 7 import org.hibernate.Transaction;
 8 import org.hibernate.cfg.Configuration;
 9 import org.junit.Test;
10 
11 import com.myproc.domain.Article;
12 import com.myproc.domain.Reply;
13 import com.myproc.domain.Topic;
14 
15 
16 public class App {
17 
18     private static SessionFactory factory=
19             new Configuration()
20             .configure()
21             .addClass(Article.class)
22             .buildSessionFactory();
23     
24     @Test
25     public void test(){
26         
27         Session session=factory.openSession();
28         Transaction tran=session.beginTransaction();
29         
30         Article article=new Article();
31         article.setTitle("article");
32         article.setContext("article.......");
33         article.setPostDate(new Date());
34         
35         Topic topic=new Topic();
36         topic.setTitle("topic");
37         topic.setContext("topic.......");
38         topic.setPostDate(new Date());
39         topic.setType(2);
40         
41         Reply reply=new Reply();
42         reply.setTitle("reply");
43         reply.setContext("reply.......");
44         reply.setPostDate(new Date());
45         reply.setFloor(1);
46         
47         session.save(article);
48         session.save(topic);
49         session.save(reply);
50         
51         tran.commit();
52         session.close();
53     }
54 }

 

  在數據庫中我們可以看到結果:

 

第二種方式:joined-subclass

  這種方式的特點:有三張表,其中父類對應的表存儲公共屬性,其它各自的表存儲各自的信息,並且在該表中用一個外鍵引用父類對應的表的主鍵,如下圖:

  

  代碼實現:在上例中,我們只需要修改Article.hbm.xml文件,內容如下:

  

 1 <?xml version="1.0"?>
 2 
 3 <!DOCTYPE hibernate-mapping PUBLIC
 4         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 5         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 6 <hibernate-mapping package="com.myproc.domain">
 7     <class name="Article" table="t_article" >
 8         <id name="id" column="Id" type="integer">
 9             <generator class="native"></generator>
10         </id>
11         <property name="title"  type="string"></property>
12         <property name="context" type="text" length="1000"></property>
13         <property name="postDate" type="timestamp"></property>
14         
15         <joined-subclass name="Topic" table="t_topic">
16             <!-- 指定子類的外鍵 -->
17             <key column="id"></key>
18             <property name="type"></property>
19         </joined-subclass>
20         
21         <joined-subclass name="Reply" table="t_reply">
22             <key column="id"></key>
23             <property name="floor"></property>
24         </joined-subclass>
25     </class>
26 </hibernate-mapping>

  當執行測試代碼后:

  在數據庫會自動生成3張表

      

  t_article表中數據:

  

  t_topic

  

  t_reply

  

  

第三種方式:union-subclass

  特點:使用兩張表存儲數據,如下圖:

  同樣只需要要修改Article.hbm.xml文件

 1 <?xml version="1.0"?>
 2 
 3 <!DOCTYPE hibernate-mapping PUBLIC
 4         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 5         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 6 <hibernate-mapping package="com.myproc.domain">
 7     <!-- 這里使用abstract=“true”,表示不再數據庫中創建對應的表(這里的類不一定是抽象類) -->
 8     <class name="Article" table="t_article" abstract="true">
 9         <id name="id" column="Id" type="integer">
10             <!-- 這里不能使用identity方式,在hibernate5.2版本也不支持hilo,這里使用MultipleHiLoPerTableGenerator,方式和hilo一樣 -->
11             <generator class="org.hibernate.id.MultipleHiLoPerTableGenerator">
12                 <param name="max_lo">100</param>
13             </generator>
14         </id>
15         <property name="title"  type="string"></property>
16         <property name="context" type="text" length="1000"></property>
17         <property name="postDate" type="timestamp"></property>
18         
19         <union-subclass name="Topic" table="t_topic">
20             <property name="type"></property>
21         </union-subclass>
22         
23         <union-subclass name="Reply" table="t_reply"></union-subclass>
24     </class>
25 </hibernate-mapping>

  在測試代碼中也不要保存Article父類型的數據

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM