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: select student_.Sid, student_1_.Name as Name0_, student_1_.Sex as Sex0_, student_1_.Age as Age0_, student_.Sno as Sno1_, student_.School as School1_ from student student_ inner join person student_1_ on student_.Sid=student_1_.id where student_.Sid=? Hibernate: insert into person (Name, Sex, Age, id) values (?, ?, ?, ?) Hibernate: insert into student (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);控制台打印的HQL Hibernate: select student0_.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_ from student student0_ inner join //与person表的Id内连接 person student0_1_ on student0_.Sid=student0_1_.id where student0_.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: select worker_.Wid, worker_1_.Name as Name0_, worker_1_.Sex as Sex0_, worker_1_.Age as Age0_, worker_.Wno as Wno2_, worker_.Salary as Salary2_ from worker worker_ inner join person worker_1_ on worker_.Wid=worker_1_.id where worker_.Wid=? Hibernate: insert into person (Name, Sex, Age, id) values (?, ?, ?, ?) Hibernate: insert into worker (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);控制台打印的HQL Hibernate: select worker0_.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_ from worker worker0_ inner join //与person表内连接 person worker0_1_ on worker0_.Wid=worker0_1_.id where worker0_.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 join out.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: select student_.Sid, student_1_.Name as Name0_, student_1_.Sex as Sex0_, student_1_.Age as Age0_, student_.Sno as Sno1_, student_.School as School1_ from student student_ inner join person student_1_ on student_.Sid=student_1_.id where student_.Sid=? Hibernate: insert into person (Name, Sex, Age, id) values (?, ?, ?, ?) Hibernate: insert into student (Sno, School, Sid) values (?, ?, ?) Hibernate: select student0_.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_ from student student0_ inner join person student0_1_ on student0_.Sid=student0_1_.id where student0_.Sid=? Hibernate: select worker_.Wid, worker_1_.Name as Name0_, worker_1_.Sex as Sex0_, worker_1_.Age as Age0_, worker_.Wno as Wno2_, worker_.Salary as Salary2_ from worker worker_ inner join person worker_1_ on worker_.Wid=worker_1_.id where worker_.Wid=? Hibernate: insert into person (Name, Sex, Age, id) values (?, ?, ?, ?) Hibernate: insert into worker (Wno, Salary, Wid) values (?, ?, ?) Hibernate: select worker0_.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_ from worker worker0_ inner join person worker0_1_ on worker0_.Wid=worker0_1_.id where worker0_.Wid=?
hibernate继承关系映射关系方法(二)--每个子类一张表
原文:http://blog.csdn.net/tuke_tuke/article/details/50082457