七、Hibernate映射继承

对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念。hibernate的集成映射可以理解为持久化类之间的继承关系。

Hibernate继承映射的三种策略:

1.基类一张表(父类、子类都在一张表中)

Animal基类:

package com.tao.entity;
/**
 * 动物基类
 * @author TaoGG
 *
 */
public class Animal {
	
	private int id;
	private String name;
	private String sex;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	@Override
	public String toString() {
		return "Animal [id=" + id + ", name=" + name + ", sex=" + sex + "]";
	}
}

Pig子类:

package com.tao.entity;

public class Pig extends Animal{
	
	private int weight;

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}

	@Override
	public String toString() {
		return "Pig [weight=" + weight + "]";
	}
	
}

Brid子类:

package com.tao.entity;

public class Brid extends Animal{
	
	private int height;

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	@Override
	public String toString() {
		return "Brid [height=" + height + "]";
	}
}

Animal.hbm.xml 配置文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.tao.entity">
	<class name="Animal" table="t_animal">
		<id name="id" column="animal_id">
			<generator class="native" />
		</id>
		<discriminator column="type" type="string"></discriminator>
		<property name="name" column="animal_name" length="100" />
		<property name="sex" column="animal_sex" length="10" />
		
		<subclass name="Pig" discriminator-value="Pig">
			<property name="weight"></property>
		</subclass>
		<subclass name="Brid" discriminator-value="Brid">
			<property name="height"></property>
		</subclass>		
	</class>
	
</hibernate-mapping>

在核心文件中引入,进行测试:

Test:

@org.junit.Test
	public void testSaveAnimal() throws Exception {
		Pig pig = new Pig();
		pig.setName("小猪佩奇");
		pig.setSex("MM");
		pig.setWeight(20);
		
		Brid brid = new Brid();
		brid.setName("小小鸟");
		brid.setSex("GG");
		brid.setHeight(10);
		
		session.save(pig);
		session.save(brid);
	}
	
	@org.junit.Test
	public void testGetAnimal() throws Exception {
		Query query = session.createQuery("from Animal");
		List<Animal> list = query.list();
		for(Animal animal:list){
			if(animal instanceof Pig){
				Pig p = (Pig) animal;
			System.out.println(p.getName()+"-"+p.getSex()+"-"+p.getWeight());
			}else{
				Brid b = (Brid) animal;
				System.out.println(b.getName()+"-"+b.getSex()+"-"+b.getHeight());
			}
		}
		
	}

 生成的数据库表结构:

输出:

Hibernate: select animal0_.animal_id as animal_i1_0_, animal0_.animal_name as animal_n3_0_, animal0_.animal_sex as animal_s4_0_, animal0_.weight as weight5_0_, animal0_.height as height6_0_, animal0_.type as type2_0_ from t_animal animal0_
小猪佩奇-MM-20
小小鸟-GG-10

2.每个类对应一张表(父类一张表,一个子类一张表):

修改映射配置文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.tao.entity">
	<class name="Animal">
		<id name="id">
			<generator class="native" />
		</id>
		<property name="name" />
		<property name="sex" />
		
		<joined-subclass name="Pig" table="t_pig">
			<key column="pid"></key>
			<property name="weight"></property>
		</joined-subclass>
		<joined-subclass name="Brid" table="t_brid">
			<key column="bid"></key>
			<property name="height"></property>
		</joined-subclass>
		
	</class>
	
</hibernate-mapping>

运行Test 生成的数据库表结构:

animal表:

t_pig表:

t_brid表:

3.每个具体的类一张表(每个子类一张表)

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.tao.entity">
	<class name="Animal" abstract="true">
		<id name="id">
			<generator class="uuid" />
		</id>
		<property name="name" />
		<property name="sex" />
		
		<union-subclass name="Pig" table="t_pig">
			<property name="weight"></property>
		</union-subclass>
		<union-subclass name="Brid" table="t_brid">
			<property name="height"></property>
		</union-subclass>
	</class>
	
</hibernate-mapping>

上面的表有个特点就是,t_pig和t_bird的主键永远都不会相同。因为表面上看起来这是两张表,但实际上存储的都是动物(同一类型),所以还可以看做是一张表。

在配置文件中 <union-subclass>标签中不需要key值了,注意Animal的主键生成策略不能是自增(native)了,如果自增的话,pig表中第一条记录id为1,bird表中第一条记录也为1,而它们在实际意义上属于同一类型(可以看做在一张表中),否则可能造成不同子类对应表中的主键相同,所以主键不可一致。

配置映射文件时,父类还用<class>标签来定义;用<union-subclass>标签定义两个子类,且每个类对应的表的信息是完全的,包含了所有从父类继承下来的属性。子类的特有属性同样用<property>定义即可。用abstract属性表示父类Animal为抽象类,这样Animal就不会映射成表了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值