Hibernate映射继承树关系

1.当父类中拥有大量子类共有属性,子类拥有极少量子类特有属性

下面用Hibernate来完成这种继承关系的映射:


Employee类:(父类)省略get和set方法

/**
 * 1.整个继承关系树对应一张表.-员工类
 */
public class Employee {
	private Integer id;
	private String name;
	private Integer age;
}

HourEmployee类:继承父类 省略get和set方法

/**
 * 临时工
 */
public class HourEmployee extends Employee {
	private float rate ;
}

SalaryEmployee类:继承父类 省略get和set方法

/**
 * 正式员工
 */
public class SalaryEmployee extends Employee {
	private float salary ;
}

只要写一个Employee.hbm.xml映射文件即可:

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.xxc.domain.Employee" table="employee" lazy="false" discriminator-value="ee"><!-- discriminator-value="ee"父类在数据库中区分字段etype的值  -->
		<id name="id" column="id" type="integer">
			<generator class="identity"></generator>
		</id>
		<!-- 必须在 id后 ,用来设置数据库中区分子类种类的字段属性-->
		<discriminator column="etype" type="string" length="2"/>
		<property name="name" column="name" type="string"/>
		<property name="age" column="age" type="integer"/>
		
		<!-- 子类映射   discriminator-value="he"表示当前映射类在数据库中区分字段etype的值 -->
		<subclass name="com.xxc.domain.HourEmployee" discriminator-value="he">
			<property name="rate" column="rate" type="float"/><!-- 配置子类特有属性就行,不用再次配父类共有属性 -->
		</subclass>
		
		<subclass name="com.xxc.domain.SalaryEmployee" discriminator-value="se">
			<property name="salary" column="salary" type="float"/>
		</subclass>
	</class>
</hibernate-mapping>


测试类:

public class App {
	private static SessionFactory sf = null;
	
	@BeforeClass
	public static void initialize(){
		Configuration config = new Configuration();
		/*  也可以写成这样的形式
		 *	sf = config.addClass(Customer.class).addClass(Order.class).buildSessionFactory();
		 */
		
		config.addClass(Employee.class);
		sf = config.buildSessionFactory();
		
	}
	
	@Test
	public void insert(){
		Session session = sf.openSession();
		Transaction t = session.beginTransaction();
		
		Employee e = new Employee();
		e.setName("ee");
		
		HourEmployee he = new HourEmployee();
		he.setName("he");
		he.setRate(500);
		
		SalaryEmployee se = new SalaryEmployee();
		se.setName("se");
		se.setSalary(1000);
		
		session.save(e);
		session.save(he);
		session.save(se);
		
		t.commit();
		session.close();
	}
	
	@Test
	public void find(){//查询子类,只需要将Form写子类类名即可。
		Session session = sf.openSession();
		Transaction t = session.beginTransaction();
		
		List list = session.createQuery("FROM HourEmployee").list();
		
		t.commit();
		session.close();
	}
}


2.当子类拥有较多子类特有属性


下面用Hibernate来完成这种继承关系的映射:

Employee和HourEmployee和SalaryEmployee三个类还是和上面一样定义,只改变了Employee.hbm.xml


Employee.hbm.xml:

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.xxc.b_domain.Employee" table="employee_join" lazy="false">
		<id name="id" column="id" type="integer">
			<generator class="identity"></generator>
		</id>
		<property name="name" column="name" type="string"/>
		<property name="age" column="age" type="integer"/>
		<!-- 连接到子类,子类自己也建表 -->
		<joined-subclass name="com.xxc.b_domain.HourEmployee" table="hourEmployee_join">
			<key column="eid"/><!-- 子类表中和父类表中有关联关系的数据库字段名 -->
			<property name="rate" column="rate" type="float"/>
		</joined-subclass>
		<joined-subclass name="com.xxc.b_domain.SalaryEmployee" table="salaryEmployee_join">
			<key column="eid"/>
			<property name="salary" column="salary" type="float"/>
		</joined-subclass>
	</class>
</hibernate-mapping>


测试类:

public class App_b {
	private static SessionFactory sf = null;
	
	@BeforeClass
	public static void initialize(){
		Configuration config = new Configuration();
		/*  也可以写成这样的形式
		 *	sf = config.addClass(Customer.class).addClass(Order.class).buildSessionFactory();
		 */
		
		config.addClass(Employee.class);
		sf = config.buildSessionFactory();
		
	}
	
	@Test
	public void insert(){
		Session session = sf.openSession();
		Transaction t = session.beginTransaction();
		
		Employee e = new Employee();
		e.setName("ee");
		
		HourEmployee he = new HourEmployee();
		he.setName("he");
		he.setRate(500);
		
		SalaryEmployee se = new SalaryEmployee();
		se.setName("se");
		se.setSalary(1000);
		
		session.save(e);
		session.save(he);
		session.save(se);
		
		t.commit();
		session.close();
	}
	
	@Test//查询子类或全部
	public void find(){
		Session session = sf.openSession();
		Transaction t = session.beginTransaction();
		/* 内连接和外连接的区别:补齐
		 * a表数据多,并多于b表且包含b表信息,a和b存在关联关系,
		 * 1.那么当进行内连接查询时,只会查询出b表和a表共有信息(内连接)
		 * 2.那么当进行外连接查询时,就会查询出a表中所有信息,a表中在b表中没有对应信息的数据也被查询出来
		 */
		String hql = "FROM HourEmployee";//因为是从子类,即从   从表开始查,那么就会内连接到主表,只查询出指定的子类的信息
		hql = "FROM Employee";//因为是从父类,即从主表开始出巡,那么就会外连接到从表,查询出所有信息,包括子类没有的

		List list = session.createQuery(hql).list();
		
		t.commit();
		session.close();
	}
	
	@Test//只是查询父类
	public void findFather(){
		Session session = sf.openSession();
		Transaction t = session.beginTransaction();
		//查询id既不在HourEmployee又不在SalaryEmployee
		String hql = "FROM Employee e WHERE e.id NOT IN(SELECT id FROM HourEmployee) AND e.id NOT IN(SELECT id FROM SalaryEmployee)";
		List list = session.createQuery(hql).list();
		
		t.commit();
		session.close();
	}
}


3.联合查询UNION

Employee和HourEmployee和SalaryEmployee三个类还是和上面一样定义,只改变了Employee.hbm.xml,测试类也和上面一样。

<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.xxc.c_domain.Employee" table="employee_union" lazy="false">
		<id name="id" column="id" type="integer">
			<generator class="hilo"><!-- 需要用hilo主键生成策略 -->
				<param name="table">hilos</param><!-- 设置存放id字段的表名 -->
				<param name="column">currentid</param><!-- 设置存放id的字段名 -->
				<param name="max_lo">10</param><!-- 设置步长 -->
			</generator>
		</id>
		<property name="name" column="name" type="string"/>
		<property name="age" column="age" type="integer"/>
		<!-- 联合子类union -->
		<union-subclass name="com.xxc.c_domain.HourEmployee" table="HourEmployee_union">
			<property name="rate" column="rate" type="float"/>
		</union-subclass>
		
		<union-subclass name="com.xxc.c_domain.SalaryEmployee" table="SalaryEmployee_union">
			<property name="salary" column="salary" type="float"/>
		</union-subclass>
	</class>
</hibernate-mapping>






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值