(十二)Hibernate继承映射

1.Hibernate中提供的三种继承映射关系.

2.重点掌握识别器的映射操作(第三种继承映射)

继承的操作之中,关注的是表的继承与类的继承对应关系,在整个Hibernate里面一共支持有如下几种继承映射关系

        ●UNION-CLASS:每个继承子表对应一个实体类;

        ●SUBCLASS:连接子类策略,识别器.(重点

        ●JOINED-SUBCLASS:每个类对应一张数据表,数据表中存在有继承关系

继承形式一:UNION-CLASS

        这种的继承关系重点只在程序的维护上,而数据表上依然会存在有重复数据;

创建web项目:HibernateSubclass

创建两张表



分别创建两个表的实体类,但是需要他们有共同的部分mid,name,age,提取出来创建父类

父类定义如下

package cn.zwb.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

/**
 * Student entity. @author MyEclipse Persistence Tools
 */
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class Member implements java.io.Serializable {

	// Fields

	private String mid;
	private String name;
	private Integer age;

	// Constructors

	/** default constructor */
	public Member() {
	}

	/** full constructor */
	public Member(String mid, String name, Integer age, String school, Double score) {
		this.mid = mid;
		this.name = name;
		this.age = age;
	}

	// Property accessors
	@Id

	@Column(name = "mid", unique = true, nullable = false)

	public String getMid() {
		return this.mid;
	}

	public void setMid(String mid) {
		this.mid = mid;
	}

	@Column(name = "name", nullable = false)

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name = "age", nullable = false)

	public Integer getAge() {
		return this.age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

}
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

以上注解表示定义的策略为一张表一个类的原则,在其他的worker类里面和stuent类里面同时写上此注解

package cn.zwb.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

/**
 * Student entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "student", catalog = "aaa")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Student extends Member implements java.io.Serializable {

	private String school;
	private Double score;

	// Constructors

	/** default constructor */
	public Student() {
	}

	/** full constructor */
	public Student(String mid, String name, Integer age, String school, Double score) {
		this.school = school;
		this.score = score;
	}


	@Column(name = "school", nullable = false)

	public String getSchool() {
		return this.school;
	}

	public void setSchool(String school) {
		this.school = school;
	}

	@Column(name = "score", nullable = false, precision = 22, scale = 0)

	public Double getScore() {
		return this.score;
	}

	public void setScore(Double score) {
		this.score = score;
	}

}
package cn.zwb.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;

/**
 * Worker entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "worker", catalog = "aaa")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Worker extends Member implements java.io.Serializable {

	private String company;
	private Double salary;

	// Constructors

	/** default constructor */
	public Worker() {
	}


	// Property accessors
	@Column(name = "company", nullable = false)

	public String getCompany() {
		return this.company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	@Column(name = "salary", nullable = false, precision = 22, scale = 0)

	public Double getSalary() {
		return this.salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}

}

并在hibernate.cfg.xml里面添加mapping的class映射,

<mapping class="cn.zwb.pojo.Member" />

此时就完成了表的配置,编写测试类测试

package cn.zwb.test;

import cn.mldn.dbc.HibernateSessionFactory;
import cn.zwb.pojo.Student;

public class Test {
	public static void main(String[] args) {
		Student stu =new Student();
		stu.setAge(100);
		stu.setMid("666");
		stu.setName("zwb");
		stu.setSchool("河南机电");
		stu.setScore(100.0);
		HibernateSessionFactory.getSession().save(stu);
		HibernateSessionFactory.getSession().beginTransaction().commit();
		HibernateSessionFactory.closeSession();
	}
}
继承形式二:JOINED-SUBCLASS


开发里面必须要回避几个问题:多表查询,1+n此查询,略

继承形式二:JOINED-SUBCLASS

        ●继承形式一(UNION):只在类结构上实现了继承以及结构的通用,但是在数据表的操作上依然会出现重复的字段,所以设计上不好;

        ●继承形式二(JOINED):在数据比啊的设计上产生了继承的关系,可是结果发现在进行数据查询的时候会存在有多表查询的操作关系.

        ●所以就发现以上的两种继承结构实际上都不好使用,那么在实际的工作之中往往会使用第三种继承关系--识别器,也就是说这些具备有类继承关系的结构定义在一张数据表中,随后使用一个字段作为区分符

继承形式二:SUBCLASS

   首先创建数据表member_subclass


type字段由hibernate进行维护

    而后使用myeclipse生成pojo类,

修改pojo类MemberSubClass;只保留公共部分 mid,name,age,并且加上abstract,加上abstract的原因是使此类不能直接使用,而通过继承使用,

package cn.zwb.pojo;

/**
 * MamberSubclass entity. @author MyEclipse Persistence Tools
 */

public class MamberSubclass implements java.io.Serializable {

	// Fields

	private String mid;
	private String name;
	private Integer age;

	// Constructors

	/** default constructor */
	public MamberSubclass() {
	}

	/** minimal constructor */
	public MamberSubclass(String mid) {
		this.mid = mid;
	}

	/** full constructor */


	// Property accessors

	public String getMid() {
		return this.mid;
	}

	public void setMid(String mid) {
		this.mid = mid;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return this.age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}


}

        然后创建Student和Worker类并继承,MamberSubclass类

package cn.zwb.pojo;

/**
 * MamberSubclass entity. @author MyEclipse Persistence Tools
 */

@SuppressWarnings("serial")
public class Student extends MamberSubclass implements java.io.Serializable {

	// Fields

	private Double score;
	private String school;
	// Constructors

	/** default constructor */
	public Student() {
	}

	public Double getScore() {
		return score;
	}

	public void setScore(Double score) {
		this.score = score;
	}

	public String getSchool() {
		return school;
	}

	public void setSchool(String school) {
		this.school = school;
	}

	/** minimal constructor */
}
package cn.zwb.pojo;

/**
 * MamberSubclass entity. @author MyEclipse Persistence Tools
 */

public class Worker extends MamberSubclass implements java.io.Serializable {

	// Fields

	private String company;
	private Double salary;

	// Constructors

	/** default constructor */
	public Worker() {
	}

	public String getCompany() {
		return company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	public Double getSalary() {
		return salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}


}

        创建过后在MamberSubclass.hbm.xml文件中配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="cn.zwb.pojo.MamberSubclass" table="mamber_subclass" catalog="aaa">
        <id name="mid" type="java.lang.String">
            <column name="mid" length="50" />
            <generator class="assigned"></generator>
        </id>
        <!--自定义识别字段 需要由hibernate自己维护type -->
        <discriminator column="type" type="java.lang.String"/>
        <property name="name" type="java.lang.String">
            <column name="name" length="50" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="age" />
        </property>
        <subclass name="cn.zwb.pojo.Student" discriminator-value="学生">
        <property name="score" type="java.lang.Double">
            <column name="score" precision="22" scale="0" />
        </property>
        <property name="school" type="java.lang.String">
            <column name="school" length="50" />
        </property>
        </subclass>
        <subclass name="cn.zwb.pojo.Worker" discriminator-value="工人">
        <property name="salary" type="java.lang.Double">
            <column name="salary" precision="22" scale="0" />
        </property>
        <property name="company" type="java.lang.String">
            <column name="company" length="50" />
        </property>
        </subclass>
    </class>
</hibernate-mapping>
      此标签表示为自定义识别字段  需要由hiberante自己维护
 <discriminator column="type" type="java.lang.String"/>

然后在里面定义Student类

 <subclass name="cn.zwb.pojo.Student" discriminator-value="学生">
        <property name="score" type="java.lang.Double">
            <column name="score" precision="22" scale="0" />
        </property>
        <property name="school" type="java.lang.String">
            <column name="school" length="50" />
        </property>
        </subclass>

接着定义Worker类

 <subclass name="cn.zwb.pojo.Worker" discriminator-value="工人">
        <property name="salary" type="java.lang.Double">
            <column name="salary" precision="22" scale="0" />
        </property>
        <property name="company" type="java.lang.String">
            <column name="company" length="50" />
        </property>
        </subclass>

此时就完成了基于*.hbm,xml文件的配置

编写测试类

package cn.zwb.test;


import cn.mldn.dbc.HibernateSessionFactory;
import cn.zwb.pojo.Student;
import cn.zwb.pojo.Worker;


public class Test {
	public static void main(String[] args) {
		Worker stu =new Worker();
		stu.setAge(100);
		stu.setMid("86776");
		stu.setName("zwb");
		stu.setCompany("公司");
		stu.setSalary(133.1);
		HibernateSessionFactory.getSession().save(stu);
		HibernateSessionFactory.getSession().beginTransaction().commit();
		HibernateSessionFactory.closeSession();
	}
}



        然后就存入进去了

\

此时的SQL语句为

        type字段的内容由Hiberante自己负责维护,而用户不需要知道它的存在,这一点的设计是实体层开发框架里面最为智能的一个

基于Anntation的配置

        早JPA的标准里面支持有Annotation的操作配置,大部分都需要用户自己来手工完成

首先创建MemberSubclass类

package cn.zwb.pojo;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * MamberSubclass entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name = "mamber_subclass", catalog = "aaa")
@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)
public abstract class MamberSubclass implements java.io.Serializable {

	// Fields

	private String mid;
	private String name;
	private Integer age;
	// Constructors

	/** default constructor */
	public MamberSubclass() {
	}

	/** minimal constructor */
	public MamberSubclass(String mid) {
		this.mid = mid;
	}

	@Id

	@Column(name = "mid", unique = true, nullable = false, length = 50)

	public String getMid() {
		return this.mid;
	}

	public void setMid(String mid) {
		this.mid = mid;
	}

	@Column(name = "name", length = 50)

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Column(name = "age")

	public Integer getAge() {
		return this.age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

}

而后在此类上定义此注解

@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)

同时创建Strudent与Worker子类

package cn.zwb.pojo;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

/**
 * MamberSubclass entity. @author MyEclipse Persistence Tools
 */
@Entity
@DiscriminatorValue("学生")
public class Student extends MamberSubclass implements java.io.Serializable {

	private Double score;
	private String school;


	@Column(name = "score", precision = 22, scale = 0)

	public Double getScore() {
		return this.score;
	}

	public void setScore(Double score) {
		this.score = score;
	}


	@Column(name = "school", length = 50)

	public String getSchool() {
		return this.school;
	}

	public void setSchool(String school) {
		this.school = school;
	}


}

ackage cn.zwb.pojo;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

/**
 * MamberSubclass entity. @author MyEclipse Persistence Tools
 */
@Entity
@DiscriminatorValue("工人")
public class Worker extends MamberSubclass implements java.io.Serializable {

	// Fields

	private String company;
	private Double salary;

	// Constructors

	/** default constructor */
	public Worker() {
	}


	@Column(name = "company", length = 50)

	public String getCompany() {
		return this.company;
	}

	public void setCompany(String company) {
		this.company = company;
	}


	@Column(name = "salary", precision = 22, scale = 0)

	public Double getSalary() {
		return this.salary;
	}

	public void setSalary(Double salary) {
		this.salary = salary;
	}

}
        分别添加此注解

@DiscriminatorValue("工人")
@DiscriminatorValue("学生")

最后在hibernate.cfg.xml里面配置如下

	<mapping class="cn.zwb.pojo.MamberSubclass" />
	<mapping class="cn.zwb.pojo.Student" />
	<mapping class="cn.zwb.pojo.Worker" />

此时配置完成,这种识别器的操作模式在实际开发之中使用的非常的多,在整个继承关系之中,识别器是一个非常重要的概念,同时Hiberante自动维护识别字段,不是所有框架都支持自动识别维护字段

总结

识别器非常重要必须掌握,

三种继承映射都具备同一个特点,类的继承结构永远保持不变,唯一改变的只是表的结构关系以及配置的定义部分

猜你喜欢

转载自blog.csdn.net/qq1019648709/article/details/80820070