TPS:所谓“每个子类一张表(Table Per Subclass)”:父类一张表,每个子类一张表,父类的表保存公共有信息,子类的表只保存自己特有的信息

这种策略是使用<joined-subclass>标签来定义子类的。父类、子类都对应一张数据库表。在父类对应的数据库表中,它存储了所 有记录的公共信息,实际上该父类对应的表会包含所有的记录,包括父类和子类的记录;在子类对应的数据库表中,这个表只定义了子类中所特有的属性映射的字 段。

person表

student表

worker表

测试工程:

Person.java

package com.hust.PO;public class Person {private Integer id;   private String name;   //姓名private Integer age;    //年龄private String sex;     //性别public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}}

Student.java

package com.hust.PO;public class Student extends Person {private Integer sid;   //学生标识,与父类person内连接private String sno;    //学号private String school;  //学校public Integer getSid() {return sid;}public void setSid(Integer sid) {this.sid = sid;}public String getSno() {return sno;}public void setSno(String sno) {this.sno = sno;}public String getSchool() {return school;}public void setSchool(String school) {this.school = school;}}

Worker.java

package com.hust.PO;public class Worker extends Person {private Integer wid;      //工人标识,与父类person内连接private String wno;      //工号private Double salary;   //工资public Integer getWid() {return wid;}public void setWid(Integer wid) {this.wid = wid;}public String getWno() {return wno;}public void setWno(String wno) {this.wno = wno;}public Double getSalary() {return salary;}public void setSalary(Double salary) {this.salary = salary;}}

映射文件Person.hbm.xml: <joined-subclass>标签需要包含一个key标签,这个标签指定了子类和父类之间是通过哪个字段来内连接的。

<?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="com.hust.PO">  <!-- Person表 -->  <class name="Person" table="person">  <!-- person 表保存公共属性 --><id name="id">  <!-- 父类的主键生成策略为‘分配’ -->  <generator class="assigned"></generator>  </id>  <property name="name" column="Name" type="string"></property>  <property name="sex" column="Sex" type="string"></property>  <property name="age" column="Age" type="java.lang.Integer"></property>  <!-- student表 ,name是类名。table是对应的表名-->  <joined-subclass name="Student" table="student">  <key column="Sid"></key>  <!-- 指定了子类和父类之间是通过哪个字段来关联的 ,这里的关联是内连接--><property column="Sno" name="sno" type="string" ></property> <!-- 子类特征属性 --><property column="School" name="school" type="string" ></property>    <!-- 子类特征属性 --></joined-subclass>  <!-- worker表 -->  <joined-subclass name="Worker" table="worker">  <key column="Wid"></key>  <property column="Wno" name="wno" type="string" ></property>  <!-- 子类特征属性 --><property column="Salary" name="salary" type="double" ></property>  <!-- 子类特征属性 --></joined-subclass>  </class>
</hibernate-mapping>  

数据库Dao文件,TableDao.java

package com.hust.Dao;import org.hibernate.Session;
import org.hibernate.Transaction;
import SessionFactory.HibernateSessionFactory;
import com.hust.PO.Student;
import com.hust.PO.Worker;public class TableDao {//保存学生信息,执行段代码后,student对象的id,name,sex,age会自动保存在person表中,特征属性sid,sno,school会保存在student表中,person表的Id字段和student表的Sid字段是内连接的public void saveStu(Student stu){Session session=HibernateSessionFactory.getSession();Transaction ts=null;try{ts=session.beginTransaction();             session.saveOrUpdate(stu);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("添加学生信息失败");}finally{HibernateSessionFactory.closeSession();}}/*session.saveOrUpdate(stu);控制台打印的HQL
Hibernate: selectstudent_.Sid,student_1_.Name as Name0_,student_1_.Sex as Sex0_,student_1_.Age as Age0_,student_.Sno as Sno1_,student_.School as School1_ fromstudent student_ inner joinperson student_1_ on student_.Sid=student_1_.id wherestudent_.Sid=?
Hibernate: insert intoperson(Name, Sex, Age, id) values(?, ?, ?, ?)
Hibernate: insert intostudent(Sno, School, Sid) values(?, ?, ?)*///加载学生信息,过程是参数id与person表内连接,查询person表的公共字段和student表的特征字段public Student loadStu(Integer id){Session session=HibernateSessionFactory.getSession();Transaction ts=null;Student stu=null;try{ts=session.beginTransaction();stu=(Student)session.get(Student.class, id);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("加载学生信息失败");}finally{HibernateSessionFactory.closeSession();}return stu;}/* stu=(Student)session.get(Student.class, id);控制台打印的HQLHibernate: selectstudent0_.Sid as id0_0_,student0_1_.Name as Name0_0_,student0_1_.Sex as Sex0_0_,student0_1_.Age as Age0_0_,student0_.Sno as Sno1_0_,student0_.School as School1_0_ fromstudent student0_ inner join  //与person表的Id内连接person student0_1_ on student0_.Sid=student0_1_.id wherestudent0_.Sid=?   //参数id是student表的Sid字段*///保存工人信息,执行段代码后,worker对象的id,name,sex,age会自动保存在person表中,特征属性wid,wno,salary会保存在worker表中,person表的Id字段和worker表的Wid字段是内连接的public void saveWorker(Worker worker){Session session=HibernateSessionFactory.getSession();Transaction ts=null;try{ts=session.beginTransaction();              session.saveOrUpdate(worker);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("添加工人信息失败");}finally{HibernateSessionFactory.closeSession();}}/*session.saveOrUpdate(worker);控制台打印的HQL
Hibernate: selectworker_.Wid,worker_1_.Name as Name0_,worker_1_.Sex as Sex0_,worker_1_.Age as Age0_,worker_.Wno as Wno2_,worker_.Salary as Salary2_ fromworker worker_ inner joinperson worker_1_ on worker_.Wid=worker_1_.id whereworker_.Wid=?
Hibernate: insert intoperson(Name, Sex, Age, id) values(?, ?, ?, ?)
Hibernate: insert intoworker(Wno, Salary, Wid) values(?, ?, ?)*///加载工人信息,过程是参数id与person表内连接,查询person表的公共字段和woker表的特征字段public Worker loadWorker(Integer id){Session session=HibernateSessionFactory.getSession();Transaction ts=null;Worker worker=null;try{ts=session.beginTransaction();worker=(Worker)session.get(Worker.class, id);ts.commit();}catch(Exception ex){ts.rollback();System.out.println("加载工人信息失败");}finally{HibernateSessionFactory.closeSession();}return worker;}/*worker=(Worker)session.get(Worker.class, id);控制台打印的HQLHibernate: selectworker0_.Wid as id0_0_,worker0_1_.Name as Name0_0_,worker0_1_.Sex as Sex0_0_,worker0_1_.Age as Age0_0_,worker0_.Wno as Wno2_0_,worker0_.Salary as Salary2_0_ fromworker worker0_ inner join  //与person表内连接person worker0_1_ on worker0_.Wid=worker0_1_.id whereworker0_.Wid=?//参数id与worker的表的Wid字段内连接
*/}

测试页面test.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.hust.Dao.*" %>
<%@ page import="com.hust.PO.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>hibernate的继承关系(二)每个子类一张表</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><!--<link rel="stylesheet" type="text/css" href="styles.css">--></head><body><h2>hibernate的继承关系(二)每个子类一张表</h2><hr><%//新建学生对象Student stu=new Student();stu.setId(new Integer(1));stu.setName("tuke");stu.setAge(new Integer(22));stu.setSex("nan");stu.setSno("M201571885");stu.setSchool("华中科技大学");//保存stu对象TableDao dao=new TableDao();dao.saveStu(stu);//从数据库中获取stu对象Student stu1=dao.loadStu(stu.getId()); //加载子类对象的时候,会使用内连接语句inner joinout.println("<br>数据库中的学生姓名:"+stu1.getName());      //共有属性out.println("<br>数据库中的学生学号:"+stu1.getSno());      //特征属性out.println("<br>数据库中的学生学校:"+stu1.getSchool());   //特征属性out.println("<br>");//新建工人对象Worker worker=new Worker();worker.setId(new Integer(2));worker.setName("李四");worker.setAge(new Integer(34));worker.setSex("nan");worker.setWno("W20152223");worker.setSalary(new Double(5435.32));//保存工人对象dao.saveWorker(worker);//从数据库中获取工人对象Worker worker2=dao.loadWorker(worker.getId()); //加载子类对象的时候,会使用内连接语句inner join、out.println("<br>数据库中的工人姓名:"+worker2.getName());  //共有属性out.println("<br>数据库中的工人工号:"+worker2.getWno());   //特征属性out.println("<br>数据库中的工人工资:"+worker2.getSalary());//特征属性%></body>
</html>

结果:


控制台打印的HQL:

Hibernate: selectstudent_.Sid,student_1_.Name as Name0_,student_1_.Sex as Sex0_,student_1_.Age as Age0_,student_.Sno as Sno1_,student_.School as School1_ fromstudent student_ inner joinperson student_1_ on student_.Sid=student_1_.id wherestudent_.Sid=?
Hibernate: insert intoperson(Name, Sex, Age, id) values(?, ?, ?, ?)
Hibernate: insert intostudent(Sno, School, Sid) values(?, ?, ?)
Hibernate: selectstudent0_.Sid as id0_0_,student0_1_.Name as Name0_0_,student0_1_.Sex as Sex0_0_,student0_1_.Age as Age0_0_,student0_.Sno as Sno1_0_,student0_.School as School1_0_ fromstudent student0_ inner joinperson student0_1_ on student0_.Sid=student0_1_.id wherestudent0_.Sid=?
Hibernate: selectworker_.Wid,worker_1_.Name as Name0_,worker_1_.Sex as Sex0_,worker_1_.Age as Age0_,worker_.Wno as Wno2_,worker_.Salary as Salary2_ fromworker worker_ inner joinperson worker_1_ on worker_.Wid=worker_1_.id whereworker_.Wid=?
Hibernate: insert intoperson(Name, Sex, Age, id) values(?, ?, ?, ?)
Hibernate: insert intoworker(Wno, Salary, Wid) values(?, ?, ?)
Hibernate: selectworker0_.Wid as id0_0_,worker0_1_.Name as Name0_0_,worker0_1_.Sex as Sex0_0_,worker0_1_.Age as Age0_0_,worker0_.Wno as Wno2_0_,worker0_.Salary as Salary2_0_ fromworker worker0_ inner joinperson worker0_1_ on worker0_.Wid=worker0_1_.id whereworker0_.Wid=?

hibernate继承关系映射关系方法(二)--每个子类一张表相关推荐

  1. 继承-----具体表继承-----每个子类一张表

    1.具体表继承:每个子类一张表,如果父类不是定义为抽象的,则父类也是一张表 (1)使用<joined-subclass>标签来定义子类. (2)父类和子类都对应一张表. (3)在父类对应的 ...

  2. java框架篇---hibernate(一对多)映射关系

    一对多关系可以分为单向和双向. 一对多关系单向 单向就是只能从一方找到另一方,通常是从主控类找到拥有外键的类(表).比如一个母亲可以有多个孩子,并且孩子有母亲的主键作为外键.母亲与孩子的关系就是一对多 ...

  3. hibernate多对多映射关系实现

    Course.hbm.xml: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC         ...

  4. oracle scott 关系图,oracle下scott用户的四张表(emp,dept,bonus,salgrade)的建表语句:

    scott用户的四张表(emp,dept,bonus,salgrade)的建表语句 emp -- Create table create table EMP ( empno NUMBER(4) not ...

  5. workflow工作流(二):34张表

    1.常用的表 2.总共34张表 Activiti的后台是有数据库的支持,所有的表都以ACT_开头. 第二部分是表示表的用途的两个字母标识. 用途也和服务的API对应. ACT_RE_*: 'RE'表示 ...

  6. hibernate继承关系映射方法(三)--每个具体类一张表TPC

    TPC:所谓是"每个具体类一张表(table per concrete class)"的意思是:使继承体系中每一个子类都对应数据库中的一张表.每一个子类对应的数据库表都包含了父类的 ...

  7. hibernate的3种继承映射关系总结——TPH,TPS,TPC

    Java类中有继承关系,相应的在hibernate中,也有继承关系,子类反应到数据库中,就有多种实现形式了,子类和父类可以映射到同一张表中,子类也可以单独映射成一张表,但是用不同的标签实现,子类表和父 ...

  8. 【大话Hibernate】Hibernate两种实体关系映射详解

    实体类与数据库之间存在某种映射关系,Hibernate依据这种映射关系完成数据的存取,因此映射关系的配置在Hibernate中是最关键的.Hibernate支持xml配置文件与@注解配置两种方式.xm ...

  9. hibernate注解方式来处理映射关系

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...

最新文章

  1. 快速撑握C#知识点系列之(struct)结构
  2. shell编程中for/while/util/case/select/break/continue
  3. 取IDE当前文档所在项目的目录[vs.net2008]
  4. Oracle 数据库linux下sql命令行按回退键变成^H字符输入问题解决方法
  5. Android_WebView加载网页保存信息到Cookie
  6. VTK:模型之CappedSphere
  7. tkinter中text属性_python tkinter基本属性详解
  8. ArcMap怎么导出shape文件到奥维互动地图
  9. mp3文件太大怎么压缩变小?
  10. android 浏览器弹窗提示,安卓手机浏览器打开网页弹出安全警告的原因及解决方法...
  11. AS中的typo作用
  12. confluence搭建
  13. 快排三种基本解法以及两种快排优化
  14. Google浏览器打开新页面会覆盖当前页面的问题(打开新页面)
  15. 【CH376】关于CH376的一些使用总结
  16. 如何轻松搞定各种图形化展现
  17. JAVA基础常见的知识点
  18. 【2020年天梯赛—校内选拔赛】7-4手机话费
  19. jsp 实现查询功能
  20. 新手如何在阿里云服务器上搭建自己的个人网站

热门文章

  1. 第七章-NoSQL数据库
  2. Python:docx模块
  3. 初等数论--整除--两数乘积保持整除性
  4. Java中的static———静态变量
  5. 关于AttributeError: type object ‘XXX‘ has no attribute ‘XXX‘的问题
  6. Web安全之命令执行漏洞
  7. 网鼎杯2020 朱雀部分writeup
  8. (34)内核编程基础
  9. linux终端窗口玩法
  10. 160个Crackme007