Hibernate (九)类的继承映射

来源:互联网 发布:目标软件游戏 编辑:程序博客网 时间:2024/05/29 02:47

有三种方式:
以论坛为例:
父类: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
原创粉丝点击