`

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

阅读更多
本示例演示Hibernate继承映射的第一种策略:每棵类继承树对应一张表

1、理解如何映射
因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。
这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:
父类用普通的<class>标签定义
在父类中定义一个discriminator,即指定这个区分的字段的名称和类型
如:<discriminator column=”XXX” type=”string”/>
子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:
Subclass标签的name属性是子类的全路径名
在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)的值
Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 
当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值是父类的全路径名称。
子类的其它属性,像普通类一样,定义在subclass标签的内部。

2、理解如何存储
在存储数据的时候,hibernate会自动将鉴别字段的值插入到数据库中,在加载数据的时候,
hibernate便能根据这个鉴别字段正确的加载对象

3、理解何为多态查询,即hibernate能够加载数据的时候自动鉴别其真正的类型

多态get(),支持
多态load(),设置Lazy=“false”时,支持
多态查询,支持 



 

 

配置如下:

测试的话先在mysql下创建数据库hibernate.再配置好下列文件放在src根目录

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.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">sys833199</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="show_sql">True</property>
		<property name="format_sql">True</property>
		<property name="use_sql_comments">True</property>
		<mapping resource="com/lwf/hibernate/extend1/ext1.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

 

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=warn, stdout

#log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug

### log HQL query parser activity
#log4j.logger.org.hibernate.hql.ast.AST=debug

### log just the SQL
#log4j.logger.org.hibernate.SQL=debug

### log JDBC bind parameters ###
log4j.logger.org.hibernate.type=info
#log4j.logger.org.hibernate.type=debug

### log schema export/update ###
log4j.logger.org.hibernate.tool.hbm2ddl=debug

### log HQL parse trees
#log4j.logger.org.hibernate.hql=debug

### log cache activity ###
#log4j.logger.org.hibernate.cache=debug

### log transaction activity
#log4j.logger.org.hibernate.transaction=debug

### log JDBC resource acquisition
#log4j.logger.org.hibernate.jdbc=debug

### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
#log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

 

 

ext1.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.lwf.hibernate.extend1">
		<class name="Animal" table="t_animal">
			<id name="id">
				<generator class="native"></generator>
			</id>
			<discriminator column="type" type="string"/>
			<property name="name"/>
			<property name="sex"/>
			<subclass name="Bird" discriminator-value="bird">
				<property name="height"/>
			</subclass>
			<subclass name="Pig" discriminator-value="pig">
				<property name="weight"/>
			</subclass>
		</class>
		
	</hibernate-mapping>

 

Animal类

package com.lwf.hibernate.extend1;

public class Animal {
	
	private int id;
	
	private String name;
	
	private boolean 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 boolean isSex() {
		return sex;
	}

	public void setSex(boolean sex) {
		this.sex = sex;
	}
	
}

 

package com.lwf.hibernate.extend1;

public class Bird extends Animal {
	
	private int height;

	public int getHeight() {
		return height;
	}

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

 

package com.lwf.hibernate.extend1;

public class Pig extends Animal {
	
	private int weight;

	public int getWeight() {
		return weight;
	}

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

 

 

上面文件建立好后,使用ExportDB类创建表.

package com.lwf.hibernate.util;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

public class ExportDB {

	public static void main(String[] args) {
		
		//读取配置文件
		Configuration cfg = new Configuration().configure();
		
		//创建SchemaExport对象
		SchemaExport export = new SchemaExport(cfg);
		
		//创建数据库表
		export.create(true,true);
	}

}

 

 

建立工具类:

package com.lwf.hibernate.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtils {
	
	private static SessionFactory factory;
	
	private HibernateUtils() {}
	
	static {
		Configuration cfg = new Configuration().configure();
		factory = cfg.buildSessionFactory();
	}
	
	public static SessionFactory getSessionFactory() {
		return factory;
	}
	
	public static Session getSession() {
		return factory.openSession();
	}
	
	public static void closeSession(Session session) {
		if (session != null) {
			if (session.isOpen()) {
				session.close();
			}
		}
	}
	
}

 

 

以下是我的测试类:

package com.lwf.hibernate.test;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;

import com.lwf.hibernate.extend1.Animal;
import com.lwf.hibernate.extend1.Bird;
import com.lwf.hibernate.extend1.Pig;
import com.lwf.hibernate.util.HibernateUtils;

public class Ext1Test  {
	
	public static void main(String[] args) {
//		testSaveAnimal();
//		testLoad1();
//		testLoad2();
		testLoad3();
		testLoad4();
//		testLoad5();
//		testLoad6();
	}
	/**
	 * 保存数据
	 *
	 */
	public static void testSaveAnimal() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Pig p = new Pig();
			p.setName("猪1");
			p.setSex(true);
			p.setWeight(400);
			
			Bird b = new Bird();
			b.setName("孔雀");
			b.setSex(true);
			b.setHeight(100);
			
			session.save(p);
			session.save(b);
			
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 通过Pig类来装载
	 *
	 */
	public static  void testLoad1() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			Pig p = (Pig)session.load(Pig.class, 1);
			System.out.println("name=" + p.getName());
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 通过Animal类来装载
	 *
	 */
	public static  void testLoad2() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			Animal a = (Animal)session.load(Animal.class, 1);
			System.out.println("name=" + a.getName());
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}

	public static void  testLoad3() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			Animal a = (Animal)session.load(Animal.class, 1);
			
			//因为我们load默认是Lazy,因为Lazy所以我们看到的是Animal的代理类
			//所以通过instance是具体反映不出真正的对象类型的
			if (a instanceof Pig) {
				System.out.println("name=" + a.getName());				
			}else {
				System.out.println("不是猪!");
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	public static  void testLoad4() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			Animal a = (Animal)session.get(Animal.class, 1);
			
			//可以正确判断,因为Animal不是代理类
			if (a instanceof Pig) {
				System.out.println("name=" + a.getName());				
			}else {
				System.out.println("不是猪!");
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	/**
	 * 将Animal的lazy设置为false
	 *
	 */
	public static void testLoad5() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			Animal a = (Animal)session.load(Animal.class, 1);
			if (a instanceof Pig) {
				System.out.println("name=" + a.getName());				
			}else {
				System.out.println("不是猪!");
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
	public static  void testLoad6() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			/**
			 * 多态查询
			 */
			List animalList = session.createQuery("from com.lwf.hibernate.extend1.Animal").list();
			
			for (Iterator iter = animalList.iterator(); iter.hasNext(); ) {
				Animal a = (Animal)iter.next();
				System.out.println("name=" + a.getName());
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			HibernateUtils.closeSession(session);
		}
	}
	
}

 

要通过对每一个测试方法的运行才能将最开始的描述有更深的认识.

上面测试类中testLoad3与testLoad4比较得知:  多态get(),支持

testLoad3与testLoad5比较得知:多态load(),设置Lazy=“false”时,支持

分享到:
评论

相关推荐

    hibernate 体系结构与配置 参考文档(html)

    混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承映射...

    Hibernate+中文文档

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承...

    Hibernate教程

    10.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 10.1.5. 每个具体类一张表(Table per concrete class) 10.1.6. Table per concrete class, using implicit polymorphism 10.1.7. 隐式多态和其他...

    HibernateAPI中文版.chm

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承...

    hibernate3.2中文文档(chm格式)

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承关系树的每个类对应一个...

    Hibernate中文详细学习文档

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承...

    最全Hibernate 参考文档

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承映射...

    Hibernate 中文 html 帮助文档

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承映射...

    Hibernate3的帮助文档

    10.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 10.1.5. 每个具体类一张表(Table per concrete class) 10.1.6. Table per concrete class, using implicit polymorphism 10.1.7. 隐式多态和其他...

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part4

     12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承关系树的每个类对应一个...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part3

     12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承关系树的每个类对应一个...

    hibernate 框架详解

    混合使用“每个类分层结构一张表”和“每个子类一张表” 10.1.5. 每个具体类一张表(Table per concrete class) 10.1.6. Table per concrete class, using implicit polymorphism 10.1.7. 隐式多态和其他继承映射...

    Hibernate实战(第2版 中文高清版)

     5.1.3 每个类层次结构一张表   5.1.4 每个子类一张表   5.1.5 混合继承策略   5.1.6 选择策略   5.2 Hibernate类型系统   5.2.1 概述实体和值类型   5.2.2 内建的映射类型   5.2.3 使用映射类型  ...

    hibernate3.04中文文档.chm

    10.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 10.1.5. 每个具体类一张表(Table per concrete class) 10.1.6. Table per concrete class, using implicit polymorphism 10.1.7. 隐式多态和其他...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part1.rar

     12.1 继承关系树的每个具体类对应一个表  12.1.1 创建映射文件  12.1.2 操纵持久化对象  12.2 继承关系树的根类对应一个表  12.2.1 创建映射文件  12.2.2 操纵持久化对象  12.3 继承关系树的每个类对应一个...

    Hibernate3+中文参考文档

    9.1.4. 混合使用“每个类分层结构一张表”和“每个子类一张表” 9.1.5. 每个具体类一张表(Table per concrete class) 9.1.6. Table per concrete class, using implicit polymorphism 9.1.7. 隐式多态和其他继承映射...

Global site tag (gtag.js) - Google Analytics