博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate笔记--继承映射关系的三种实现方式
阅读量:4708 次
发布时间:2019-06-10

本文共 3794 字,大约阅读时间需要 12 分钟。

单表继承映射(一张表): 

 假设我们现在有三个类,关系如下:

         

  Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映射来建表,最后生成的表是这样的:

  可以看到我们只需要建立一张表就可以维护这个关系,这种方式就是单表继承映射,下面介绍配置方法:

  新建实体类Person ,Student,和Teacher :

public class Person {    private int id;    private String name;    private int age;//ge/set方法省略}/****************/public class Student extends Person{    private String homework;//ge/set方法省略}/****************/public class Teacher extends Person{    private int salary;//ge/set方法省略}

 

  在当前包下新建Person类的映射文件Person.hbm.xml:

 

将Person.hbm.xml添加到hibernate.cfg.xml中. 新建一个测试类,测试1:自动生成数据库表 2:保存数据 3:读取数据(分别测试get方式 和 load方式 取数据,观察不同点):

@Test    public void testCreateDB() {        Configuration cfg = new Configuration().configure();        SchemaExport se = new SchemaExport(cfg);        // 第一个参数是否生成ddl脚本 第二个参数是否执行到数据库        se.create(true, true);    }    @Test    public void testSave() {        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        Teacher t1=new Teacher();        t1.setName("洪七公");        t1.setAge(65);        t1.setSalary(7000);        Student s1=new Student();        s1.setName("郭靖");        s1.setAge(26);        s1.setHomework("降龙十八掌");        Student s2=new Student();        s2.setName("黄蓉");        s2.setAge(23);        s2.setHomework("打狗棒法");        session.save(t1);        session.save(s1);        session.save(s2);                tx.commit();        session.close();    }        @Test    public void testGet() {        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        Person p=(Person)session.get(Person.class, 2);        System.out.println("name:"+p.getName());        if(p instanceof Student){            Student s=(Student)p;            System.out.println("homework:"+s.getHomework());        }        tx.commit();        session.close();    }    @Test    public void testLoad() {        Session session = HibernateUtil.getSession();        Transaction tx = session.beginTransaction();        Person p=(Person)session.load(Person.class, 2);        System.out.println("name:"+p.getName());        if(p instanceof Student){            Student s=(Student)p;            System.out.println("homework:"+s.getHomework());        }        tx.commit();        session.close();    }

 

注意:

  在单表继承映射中,hibernate通过鉴别器 <discriminator>来识别不同的类,鉴别器由hibernate来维护.

  查询数据时,如果是使用session.get(...)方式获取到的类,可以进行多态的判断,如果是使用session.load(...)方式获取到的类,则不能进行多态的判断,在上面的testGet和testLoad中,打印出来的内容分别是:

name:郭靖

homeword:降龙十八掌

name:郭靖

可以看出,使用load方法,程序并没有进入通过if语句的判断.

 每个子类对应一张表的继承映射(两张表):

  同样是上面的例子,我们也可以通过多张表来实现上述的继承关系,这种方式会分别生成Student表和Teacher表,结构是这样的:

teacher表:                                                                  Student表

                                

 实体类是不需要改变的,只需要改变Person.hbm.xml即可:

 

注意::

  在这种继承映射中,主键的生成方式不能设置为native,可以使用uuid,assigned,sequence等.

  这种表的生成方式更加合理,但是查询的效率不高.

每个类对应一张表的继承映射(3张表):

  上面的例子是使用两张表来实现继承映射的,其实还可以用三张表的方式,即Person,Student,Teacher各对应一张表,Person中保存公共属性的信息,Studnet,Teacher表中只保存自己独有的属性,表结构如下:

                                  

同样只需要修改Person.hbm.xml文件即可:

三种映射方式的比较:

  1.   第一种方式,只有一张表,数据冗余较多,但查询效率高,数据量不是非常大的时候,推荐使用.
  2.   第二种方式,每个子类对应一张表,数据冗余比较少,查询效率不高,主键不能设置成自增(native),需要指明为assigned,uuid,等.
  3.   第三种方式,每个类对应一张表,数据冗余较少,查询效率比第二种方式稍高,需要维护的表的个数较多.

转载于:https://www.cnblogs.com/fingerboy/p/5243158.html

你可能感兴趣的文章
高质量程序设计指南c++/c语言(20)--符号常量
查看>>
strncpy实现
查看>>
华为机试——字符倒叙输出
查看>>
C#程序开发中经常遇到的10条实用的代码
查看>>
Describe the difference between repeater, bridge and router.
查看>>
最小生成树--牛客练习赛43-C
查看>>
SQLite3中dos命令下退出"...>"状态的方法
查看>>
Element-ui 实现table的合计功能
查看>>
这个网站的导航配色很喜欢
查看>>
Android之背景选择器selector用法汇总
查看>>
Java读文件
查看>>
windows下启动mysql服务的命令行启动和手动启动方法
查看>>
识别网络应用所使用的协议Amap
查看>>
iOS 9应用开发教程之显示编辑文本标签文本框
查看>>
puppet安装
查看>>
博客中的文本编辑器+源码下载
查看>>
linux内核情景分析之强制性调度
查看>>
用于生日计算的参数
查看>>
matlab中如何根据t检验参数查找t检验值
查看>>
《JAVA核心技术》观后感
查看>>