Hibernate (九)类的继承映射

有三种方式:
以论坛为例:
父类:Article.java
主帖:Topic extend Article
回复:Reply extend Article

方案一:
由于大部分属性相同,可以只创建一个表,存放所有数据,没有的就填写null,用类型来分辨 具体类型。

方案二:
创建三个表,每个表都只有自己的属性。

方案三:
创建两个子表,两个子表都拥有父类表的属性:

看代码:

public class Article {
    private Integer id;
    private String title;
    private String content;
    private Date postTime;
    ...
}
public class Reply extends Article {
    private int floor; // 楼层
    ...
}

public class Topic extends Article {
    private int type; // 精华、置顶...
    ...
}

下面是三种映射方式
方案一(一张表):

<?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 package="cn.itcast.j_hbm_extends">
    <!-- 
        discriminator-value属性:
            用于鉴别是哪个类的一个值,表示这个值就是这个类。
            如果不写,默认为类的全限定名。
     -->
    <class name="Article" table="article" discriminator-value="Aticle">
        <id name="id">
            <generator class="native"/>
        </id>

        <!-- 用于鉴别是什么类型的一个列 -->
        <discriminator type="string" column="class_"></discriminator>

        <property name="title"/>
        <property name="content" type="text" length="10000"/>
        <property name="postTime" type="timestamp"/>


        <!-- 子类:Topic -->
        <subclass name="Topic" discriminator-value="Topic">
            <property name="type"></property>
        </subclass>


        <!-- 子类:Reply -->
        <subclass name="Reply" discriminator-value="Reply">
            <property name="floor"></property>
        </subclass>

    </class>

</hibernate-mapping>

方案二 (三张表)

<?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 package="cn.itcast.j_hbm_extends2">

    <!-- 采用每个类一张表的方式,抽象类也对应表。 -->
    <class name="Article" table="article2">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="title"/>
        <property name="content" type="text" length="10000"/>
        <property name="postTime" type="timestamp"/>


        <!-- 子类:Topic -->
        <joined-subclass name="Topic" table="topic2">
            <key column="id"></key>
            <property name="type"></property>
        </joined-subclass>


        <!-- 子类:Reply -->
        <joined-subclass name="Reply" table="reply2">
            <key column="id"></key>
            <property name="floor"></property>
        </joined-subclass>

    </class>

</hibernate-mapping>

方案三(两种表)

<?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 package="cn.itcast.j_hbm_extends3">

    <!-- 采用每个具体类一张表的方式,抽象类不对应表。
        abstract默认为false,设为true表示本类不对应表(类可以不是abstract的),这时就会忽略table属性。
     -->
    <class name="Article" abstract="false" table="article3">
        <id name="id">
            <!-- 
                当使用每个具体类一张表的方式时,主键生成策略不能是identity。
                因为在整个继承结构中,主键值是不能重复的。
             -->
            <generator class="hilo">
                <param name="table">hi_value</param>
                <param name="column">next_value</param>
                <param name="max_lo">100</param>
            </generator>
        </id>
        <property name="title"/>
        <property name="content" type="text" length="10000"/>
        <property name="postTime" type="timestamp"/>

        <!-- 子类:Topic -->
        <union-subclass name="Topic" table="topic3">
            <property name="type"></property>
        </union-subclass>

        <!-- 子类:Reply -->
        <union-subclass name="Reply" table="reply3">
            <property name="floor"></property>
        </union-subclass>
    </class>
</hibernate-mapping>

测试代码:

package cn.itcast.j_hbm_extends3;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

public class App {

    private static SessionFactory sessionFactory = new Configuration()//
            .configure()//
            .addClass(Article.class)// 添加Hibernate实体类(加载对应的映射文件)
            .buildSessionFactory();

    // 保存,有关联关系
    @Test
    public void testSave() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        // 新建对象
        Article article = new Article();
        article.setTitle("这是一个Article");

        Topic topic = new Topic();
        topic.setTitle("这是一个Topic");

        Reply reply = new Reply();
        reply.setTitle("这是一个Reply");

        // 保存
        session.save(article);
        session.save(topic);
        session.save(reply);

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();
    }

    // 获取,可以获取到关联的对方
    @Test
    public void testGet() throws Exception {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        // --------------------------------------------

        // 获取
        Article article = (Article) session.get(Article.class, 1);
        Topic topic = (Topic) session.get(Topic.class, 2);
        Reply reply = (Reply) session.get(Reply.class, 3);

        System.out.println(article);
        System.out.println(topic);
        System.out.println(reply);
        System.out.println();

        Article article1 = (Article) session.get(Article.class, 2);
        Article article2 = (Article) session.get(Article.class, 3);
        System.out.println(article1);
        System.out.println(article2);

        // --------------------------------------------
        session.getTransaction().commit();
        session.close();

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值