Hibernate继承关系映射

        1)使用一张表

            1> 原理:使用一张表来保存父类和子类中的所有字段,并通过一个字段来区别不同的类

            2> pojo设计

              父类:

public class Article {
	private int id;
	private String title;
	private Date date;
	private String content;
}
             子类:

public class Topic extends Article {
	private int type;//表示是精华、置顶...
}
public class Replay extends Article {
	private int floor;
}
             3> 映射文件

               注:映射文件要和父类同名

</pre><pre name="code" class="html"> <class name="cn.com.cpf.pojo.Article"   table="t_article">
  <id name="id" column="id">
      <generator class="native"/>
  </id>
  <discriminator column="class_" type="string"/>
  <property name="content" length="500" type="text"/>
  <property name="date" type="timestamp"/>
  <property name="title"/>
  <subclass name="cn.com.cpf.pojo.Topic" discriminator-value="Topic">
       <property name="type" type="int"/>
  </subclass>
  
  <subclass name="cn.com.cpf.pojo.Replay" discriminator-value="Replay">
      <property name="floor"/>
  </subclass>
 </class>


</pre>           说明:</p><p>          1.discriminator标签用来在一个表中区别不同的类,column指定保存区别的字段</p><p>          2.subcla标签用来指定子类的特有属性,name为子类的全名,discriminator-value用来指定在区别字段中的值,默认的是类的全名         4> 生成的数据库表结构</p><p>         <img src="https://img-blog.youkuaiyun.com/20140811180552659" alt="" />        5> 保存操作</p><p><pre name="code" class="java">       factory = new Configuration().configure().buildSessionFactory();
       session = factory.openSession();
       Transaction tx = session.beginTransaction();

       Article article = new Article();
       article.setTitle("this is a article");
       Topic topic = new Topic();
       topic.setTitle("this is a topic");
       Replay replay = new Replay();
       replay.setTitle("this is a replay");

       session.save(article);
       session.save(topic);
       session.save(replay);

       tx.commit();
           结果为:

           

        6> 获取操作

       Article article1 = (Article) session.get(Article.class, 1);
       Topic article2 = (Topic) session.get(Topic.class, 2);
       Replay article3 = (Replay) session.get(Replay.class, 3);
       System.out.println(article1.getTitle());
       System.out.println(article2.getTitle());
       System.out.println(article3.getTitle());
           结果为:

Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
Hibernate: select topic0_.id as id1_2_0_, topic0_.content as content3_2_0_, topic0_.date as date4_2_0_, topic0_.title as title5_2_0_, topic0_.type as type6_2_0_ from t_article topic0_ where topic0_.id=? and topic0_.class_='Topic'
Hibernate: select replay0_.id as id1_2_0_, replay0_.content as content3_2_0_, replay0_.date as date4_2_0_, replay0_.title as title5_2_0_, replay0_.floor as floor7_2_0_ from t_article replay0_ where replay0_.id=? and replay0_.class_='Replay'
this is a article
this is a topic
this is a replay
             或者:

        Article article1 = (Article) session.get(Article.class, 1);
        Article article2 = (Article) session.get(Article.class, 2);
        Article article3 = (Article) session.get(Article.class, 3);
        System.out.println(article1.getTitle());
        System.out.println(article2.getTitle());
        System.out.println(article3.getTitle());
           结果为:

Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
Hibernate: select article0_.id as id1_2_0_, article0_.content as content3_2_0_, article0_.date as date4_2_0_, article0_.title as title5_2_0_, article0_.type as type6_2_0_, article0_.floor as floor7_2_0_, article0_.class_ as class_2_2_0_ from t_article article0_ where article0_.id=?
this is a article
this is a topic
this is a replay
        2)每个类均使用一张表(包括抽象类)
             1> 原理:

                  1.父类对应表中存放公共字段,子类中仅存放自己特有的

                  2.子类对应表通过主键关联和父类进行一对一映射

             2> 映射文件

 <class name="cn.com.cpf.pojo.Article"   table="t_article2">
  <id name="id" column="id">
  	<generator class="native"/>
  </id>
  <property name="content" length="500" type="text"/>
  <property name="date" type="timestamp"/>
  <property name="title"/>

  <joined-subclass name="cn.com.cpf.pojo.Topic" table="t_topic2">
   <key column="aid"/>
   <property name="type"/>
  </joined-subclass>
  <joined-subclass name="cn.com.cpf.pojo.Replay" table="t_replay2">
   <key column="aid"/>
   <property name="floor"/>
  </joined-subclass>
 </class>
           3> 生成的表结构

               父类表结构:

       
             子类Topic表结构
         
        

          子类Replay表结构

        

       

          4> 保存

        Article article = new Article();
        article.setTitle("this is a article");
        Topic topic = new Topic();
        topic.setTitle("this is a topic");
        Replay replay = new Replay();
        replay.setTitle("this is a replay");

        session.save(article);
        session.save(topic);
	session.save(replay);
           结果为:

          

         

         
       3)每一个具体类均对应一张表(抽象类不对应)

            1> 原理:

                  子类对应表包含所有字段,包括父类中的

             2> 映射文件

 <class name="cn.com.cpf.pojo.Article"  abstract="true" table="t_article2">
   <id name="id" column="id">
  	<generator class="hilo">
        <param name="table">hi_value</param>
        <param name="column">next_value</param>
        <param name="max_lo">10</param>
    </generator>
  </id>
  <property name="content" length="500" type="text"/>
  <property name="date" type="timestamp"/>
  <property name="title"/>

  <union-subclass name="cn.com.cpf.pojo.Topic" table="t_topic3">
  	<property name="type"/>
  </union-subclass>
  <union-subclass name="cn.com.cpf.pojo.Replay" table="t_replay3">
  	<property name="floor"/>
  </union-subclass>
 </class>
               说明:

               1.如果注明abstract=true,那么就不会生成表

               2.使用这种继承方式,id生成方式不能为identity(因为要求整个继承体系中id均为唯一的,这样才能使用多态的特性,而identity是数据库自动生成,极有可能对topic和replay表生成相同的id,这样通过Article.class来查找的时候就无法确定找出来的是哪一个)
            3> 生成的数据库表结构

              topic表:

              

           replay表:

             

           4> 保存              

         Article article = new Article();
         article.setTitle("this is a article");
         Topic topic = new Topic();
         topic.setTitle("this is a topic");
         Replay replay = new Replay();
         replay.setTitle("this is a replay");

         session.save(article);
         session.save(topic);
         session.save(replay);
           结果为:

          

         

       4) 总结

           继承结构一般很少使用,因为需要查找多张表,效率会低


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值