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

2015-11-28 17:36

TPC:所谓是“每个具体类一张表(table per concrete class)”的意思是:使继承体系中每一个子类都对应数据库中的一张表。每一个子类对应的数据库表都包含了父类的信息,并且包含了自己独有的属性。每个子类对应一张表,而且这个表的信息是完备的,即包含了所有从父类继承下来的属性映射的字段。这种策略是使用<union-subclass>标签来定义子类的。

hibernate继承关系映射方法(三)每个具体类一张表TPC0hibernate继承关系映射方法(三)每个具体类一张表TPC1

注意:三个类+一个父类映射文件+两张表

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

student表

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

worker表

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

测试工程:

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

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 String sno;    //学号
       private String school;  //学校
    	
	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 String wno;      //工号
     private Double salary;   //工资
   

	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

<?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">  
    <!-- table per concrete(TPC) (a. 具体的,实际的) -->  
    <!-- 每一个具体类一张表 -->  
    <!-- 虚拟选项为'true' -->  
    <class name="Person" table="person" abstract="true">  <!-- 多设置一个属性abstract="true",因为根本就没有person表 -->
    <id column="Id" name="id" type="integer">  
        <!-- 主键的生成策略为'分配' -->  
        <generator class="assigned"></generator>  
    </id>  
    <property column="Name" name="name" type="string"></property>  
    <property column="Sex" name="sex" type="string"></property>  
    <property column="Age" name="age" type="integer"></property>  <!-- 公共属性 -->
      
    <!--student具体类-->  
    <union-subclass name="Student" table="student">  
        <property column="Sno" name="sno" type="string"></property>      <!-- 特征属性 --> 
        <property column="School" name="school" type="string"></property>  <!-- 特征属性 -->
    </union-subclass>  
      
    <!--worker具体类-->  
    <union-subclass name="Worker" table="worker">  
        <property column="Wno" name="wno" type="string"></property>  <!-- 特征属性 -->
        <property column="Salary" name="salary" type="double"></property>  <!-- 特征属性 -->
    </union-subclass>  
      
    </class>  
</hibernate-mapping>  
<union-subclass>标签是用于指示出该hbm文件所表示的类的子类,如Person类有两个子 类,就需要两个<union-subclass>标签以此类推。

<union-subclass>标签的"name"属性用于指 定子类的全限定名称,"table"属性用于指定该子类对应的表的名称,"extends"属性用于指定该子类的父类,

注意:"extends"属性与<union-subclass>标签的位置有关,若<union-subclass>标签作为<class>标签的子标签,则"extends"属性可以不设置,否则需要明确设置"extends"属性。

<class>标签中的"abstract"属性如果值为true则,不会生成表结构。如果值为false则会生成表结构,但是不会插入数据。

数据库文件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 {
     //保存学生信息
	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_.Id,
        student_.Name as Name0_,
        student_.Sex as Sex0_,
        student_.Age as Age0_,
        student_.Sno as Sno1_,
        student_.School as School1_ 
    from
        student student_ 
    where
        student_.Id=?
Hibernate: 
    insert 
    into
        student
        (Name, Sex, Age, Sno, School, Id) 
    values
        (?, ?, ?, ?, ?, ?)
*/
	//加载学生信息
	 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_.Id as Id0_0_,
        student0_.Name as Name0_0_,
        student0_.Sex as Sex0_0_,
        student0_.Age as Age0_0_,
        student0_.Sno as Sno1_0_,
        student0_.School as School1_0_ 
    from
        student student0_ 
    where
        student0_.Id=?*/
	//保存工人信息
		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_.Id,
        worker_.Name as Name0_,
        worker_.Sex as Sex0_,
        worker_.Age as Age0_,
        worker_.Wno as Wno2_,
        worker_.Salary as Salary2_ 
    from
        worker worker_ 
    where
        worker_.Id=?
        Hibernate: 
    insert 
    into
        worker
        (Name, Sex, Age, Wno, Salary, Id) 
    values
        (?, ?, ?, ?, ?, ?)
*/
		//加载工人信息
		 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_.Id as Id0_0_,
        worker0_.Name as Name0_0_,
        worker0_.Sex as Sex0_0_,
        worker0_.Age as Age0_0_,
        worker0_.Wno as Wno2_0_,
        worker0_.Salary as Salary2_0_ 
    from
        worker worker0_ 
    where
        worker0_.Id=?

		
*/
	
}
测试页面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的继承关系(三)每个具体类一张表TPC</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的继承关系(三)--每个具体类一张表TPC</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()); //加载子类对象
               
               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>
测试结果:

hibernate继承关系映射方法(三)每个具体类一张表TPC6
student表插入的值:

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

worker表插入的值:

hibernate继承关系映射方法(三)每个具体类一张表TPC8
控制台打印店的HQL

Hibernate: 
    select
        student_.Id,
        student_.Name as Name0_,
        student_.Sex as Sex0_,
        student_.Age as Age0_,
        student_.Sno as Sno1_,
        student_.School as School1_ 
    from
        student student_ 
    where
        student_.Id=?
Hibernate: 
    insert 
    into
        student
        (Name, Sex, Age, Sno, School, Id) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    select
        student0_.Id as Id0_0_,
        student0_.Name as Name0_0_,
        student0_.Sex as Sex0_0_,
        student0_.Age as Age0_0_,
        student0_.Sno as Sno1_0_,
        student0_.School as School1_0_ 
    from
        student student0_ 
    where
        student0_.Id=?
Hibernate: 
    select
        worker_.Id,
        worker_.Name as Name0_,
        worker_.Sex as Sex0_,
        worker_.Age as Age0_,
        worker_.Wno as Wno2_,
        worker_.Salary as Salary2_ 
    from
        worker worker_ 
    where
        worker_.Id=?
Hibernate: 
    insert 
    into
        worker
        (Name, Sex, Age, Wno, Salary, Id) 
    values
        (?, ?, ?, ?, ?, ?)
Hibernate: 
    select
        worker0_.Id as Id0_0_,
        worker0_.Name as Name0_0_,
        worker0_.Sex as Sex0_0_,
        worker0_.Age as Age0_0_,
        worker0_.Wno as Wno2_0_,
        worker0_.Salary as Salary2_0_ 
    from
        worker worker0_ 
    where
        worker0_.Id=?