`

hibernate学习9之extends(继承)映射

阅读更多
hibernate.cfg.xml:
<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_extends_1</property>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">bjsxt</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.show_sql">true</property>
		
		<mapping resource="com/bjsxt/hibernate/extends.hbm.xml"/>
	</session-factory>
</hibernate-configuration>


假定有2个子类Pig,Bird,他们都继承自Animal
public class Animal {
	private int id;
	private String name;
	private boolean sex;
	//setter,getter
}
public class Pig extends Animal {	
	private int weight;
	//setter,getter
}
public class Pig extends Animal {
	private int height;
	//setter,getter
}

他们的映射关系可以像下面那样,这样可以把Pig 和Bird存在同一张表里,以外键字段type区分存的是Pig还是Bird
<?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.bjsxt.hibernate">
	<class name="Animal" table="t_animal">
		<id name="id">
			<generator class="native"/>
		</id>
        <!--加入鉴别器,用以判断是Pig还是Bird-->
		<discriminator column="type" type="string"/>
		<property name="name"/>
		<property name="sex"/>
		<subclass name="Pig" discriminator-value="P">
			<property name="weight"/>
		</subclass>
		<subclass name="Bird" discriminator-value="B">
			<property name="height"/>
		</subclass>
	</class>
</hibernate-mapping>

测试一下:
import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;

import junit.framework.TestCase;

public class ExtendsTest extends TestCase {

	public void testSave1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Pig pig = new Pig();
			pig.setName("猪猪");
			pig.setSex(true);
			pig.setWeight(100);
			session.save(pig);
			
			Bird bird = new Bird();
			bird.setName("鸟鸟");
			bird.setSex(false);
			bird.setHeight(50);
			session.save(bird);
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	
	
	/**
	 * 采用load,通过Pig查询
	 */
	public void testLoad1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Pig pig = (Pig)session.load(Pig.class, 1);
			System.out.println(pig.getName());
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 采用load,通过Animal查询
	 */
	public void testLoad2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Animal animal = (Animal)session.load(Animal.class, 1);
			System.out.println(animal.getName());
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}			
	
	/**
	 * 采用load,通过Animal查询
	 */
	public void testLoad3() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Animal animal = (Animal)session.load(Animal.class, 1);
			
			//因为load默认只是lazy,因为我们看到的是Animal的代理对象
			//所以通过instanceof是反应不出正真的对象类型的
			//因此load在默认情况下是不支持多态查询的
			if (animal instanceof Pig) {
				System.out.println(animal.getName());
			}else {
				System.out.println("不是猪");
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}			
	
	/**
	 * 采用load,通过Animal查询,将<class>标签上的lazy=false
	 */
	public void testLoad4() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			Animal animal = (Animal)session.load(Animal.class, 1);
			//可以正确的判断出Pig的类型,因为lazy=false,返回的是具体的Pig类型
			//此时load支持多态查询
			if (animal instanceof Pig) {
				System.out.println(animal.getName());
			}else {
				System.out.println("不是猪");
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}		
	
	/**
	 * 采用get,通过Animal查询
	 */
	public void testLoad5() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			
			//可以正确的判断出Pig的类型,因为返回的是具体的Pig类型
			//get支持多态查询
			Animal animal = (Animal)session.get(Animal.class, 1);

			if (animal instanceof Pig) {
				System.out.println(animal.getName());
			}else {
				System.out.println("不是猪");
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	
	
	/**
	 * 采用get,通过Animal查询
	 */
	public void testLoad6() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
//			List animalList = session.createQuery("from Animal").list();
//			for (Iterator iter = animalList.iterator(); iter.hasNext();) {
//				Animal a = (Animal)iter.next();
//				//能够正确的鉴别出正真的类型,hql是支持多态查询的
//				if (a instanceof Pig) {
//					System.out.println("是Pig");
//				}else if (a instanceof Bird) {
//					System.out.println("是bird");
//				} 
//			}
			
			List list = session.createQuery("from java.lang.Object").list();
			for (Iterator iter=list.iterator(); iter.hasNext();) {
				Object o = iter.next();
				if (o instanceof Pig) {
					System.out.println("是Pig");
				}else if (o instanceof Bird) {
					System.out.println("是bird");
				} 
			}
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}	
	
}



多态查询:在hibernate加载数据的时候能鉴别出正真的类型(instanceOf)

get支持多态查询
load只有在lazy=false,才支持多态查询
hql支持多态查询

例外还有一种继承映射关系可以生成3张表(每个类生成一张表,不管是父类还是子类),配置关系如下,不过效率和维护关系比较复杂,不推荐使用。
<?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.bjsxt.hibernate">
	<class name="Animal" table="t_animal">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<property name="sex"/>
		<joined-subclass name="Pig" table="t_pig">
			<key column="pid"/>
			<property name="weight"/>
		</joined-subclass>
		<joined-subclass name="Bird" table="t_bird">
			<key column="bid"/>
			<property name="height"/>
		</joined-subclass>
	</class>
</hibernate-mapping>
分享到:
评论

相关推荐

    Hibernate教程17_继承映射_补充1

    "Table Per Class"策略,也称为全表继承,是Hibernate支持的继承映射策略之一。在这一策略中,每个类都会映射到数据库中的一个独立表。这意味着,如果你有一个类层次结构,基类和所有子类都会各自对应一个表。每个表...

    Hibernate教程17_继承映射_补充2

    在本教程中,我们将深入探讨Hibernate中的继承映射,特别是在"Hibernate教程17_继承映射_补充2"中所涉及的主题。Hibernate是Java中一个非常流行的对象关系映射(ORM)框架,它允许开发者用面向对象的方式处理数据库...

    Hibernate继承映射-概述

    《Hibernate继承映射详解》 在Java开发中,对象关系映射(ORM)框架如Hibernate大大简化了数据库操作。Hibernate不仅提供了对基本数据类型的映射,还支持复杂的数据结构,如继承关系的映射。本篇文章将深入探讨...

    Hibernate继承映射的第一种策略:每棵类继承树对应一张表

    Hibernate继承映射是将Java类的继承关系映射到数据库表的一种策略,使得对象模型的复杂性能够平滑地转化为关系数据库模型。本篇将详细介绍Hibernate继承映射的第一种策略——每棵类继承树对应一张表,即单一表继承...

    Hibernate继承映射(annotation)

    **标题:“Hibernate继承映射(Annotation)详解”** 在Java持久化框架Hibernate中,继承映射是一种关键特性,它允许开发者将对象模型的继承结构映射到数据库的表结构。在传统的面向对象编程中,继承是实现代码复用和...

    hibernate 映射继承 demo

    Hibernate支持四种继承映射策略:单表继承(Single Table Inheritance)、联合继承( Joined Subclass)、表 per 类继承(Table per Class Inheritance)和子类表(Concrete Table Inheritance)。在实际应用中,最...

    Hibernate继承映射的第一种策略:每个具体类一张表

    本篇文章将详细探讨Hibernate继承映射的策略,特别是“每个具体类一张表”(Table Per Concrete Class)的映射方式。 在面向对象编程中,继承是常见的代码复用手段,但在关系型数据库中,这种概念并不直接对应。...

    (2)Hibernate3.2 中的类继承关系

    本话题主要探讨的是Hibernate 3.2版本中的类继承关系处理,这是面向对象编程中常见的概念,但在数据库映射时需要特殊考虑。在Hibernate中,类继承关系的处理允许我们创建更加灵活和可扩展的对象模型。 在Hibernate ...

    hibernate的继承映射(InheritanceMapping)[文].pdf

    本文将深入探讨Hibernate中的继承映射(Inheritance Mapping)策略,这是处理对象模型中继承关系在数据库中的映射方式。 10.1. Hibernate继承映射的三种基本策略: 10.1.1. 每个类分层结构一张表(Table per class...

    Hibernate继承映射的第一种策略:每个类对应一张表

    在Java的持久化框架Hibernate中,继承映射是处理对象模型中类继承关系的重要机制。本文将详细探讨“Hibernate继承映射的第一种策略:每个类对应一张表”的概念、实现方式以及其优缺点。 首先,我们需要理解...

    Hibernate继承映射一:每个类分层结构一张表

    这种映射策略是Hibernate提供的多种继承映射方案之一,适用于处理复杂的对象模型。 首先,我们要理解什么是继承映射。在面向对象编程中,类可以继承自其他类,形成类的继承树。在数据库中,如果要存储这些继承关系...

    Hibernate继承映射

    【Hibernate继承映射】是Java开发中使用Hibernate框架进行数据持久化时的一种重要技术,它允许我们将复杂的对象模型映射到数据库的表结构上。在实际项目中,我们经常遇到对象之间的继承关系,如抽象类和子类。...

    让Hibernate同时支持xml和注解两种映射方式

    在Java企业级开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者以面向对象的方式处理数据库操作。Hibernate支持两种主要的映射方式:XML映射文件和注解映射。然而,默认情况下,一个项目只能...

    Hibernate ORM - 继承关联关系之union-subclass

    总的来说,“union-subclass”是Hibernate提供的一种处理继承关系的方法,它允许我们有效地将复杂的面向对象设计映射到数据库中,同时也为我们的查询提供了灵活性。在实际开发中,熟练掌握和运用这种策略,可以提高...

    hibernate源码下载

    `hibernate_extends_1`和`hibernate_extends_3`可能涉及到Hibernate的继承映射和扩展机制。在Hibernate中,可以通过@Entity和@Inheritance注解来处理类的继承关系,支持JOINED、SINGLE_TABLE和TABLE_PER_CLASS三种...

    Hibernate 经典例子全

    `hibernate_extends_1`和`hibernate_extends_2`展示了Hibernate如何处理类的继承关系。Hibernate支持单继承和多层继承的映射,通过`&lt;subclass&gt;`或`&lt;joined-subclass&gt;`标签将子类映射到数据库中的特定表,这在设计...

Global site tag (gtag.js) - Google Analytics