zoukankan      html  css  js  c++  java
  • 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父类型的数据

     

  • 相关阅读:
    取一定范围的随机数
    小菜学Chromium之OpenGL学习之二
    程序员健康之路
    解密硬件解码关键技术
    Android 图片开发内幕系列第一篇
    你所不知道的html5与html中的那些事第三篇
    如何加密android apk
    linux设备驱动第五篇:驱动中的并发与竟态
    快速调试chromium
    小菜鸟带着梦想学chromium
  • 原文地址:https://www.cnblogs.com/caoyc/p/5603724.html
Copyright © 2011-2022 走看看