Hibernate继承映射三:每个具体类一张表

每个具体类一张表

我们看看这种配置需要怎么做?

 

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

1、如何映射
这种策略是使用union-subclass标签来定义子类的。每个子类对应一张表,而且这个表的信息是完备的,
即包含了所有从父类继承下来的属性映射的字段(这就是它跟joined-subclass的不同之处,joined-subclass定义的子类的表,
只包含子类特有属性映射的字段)。实现这种策略的时候,有如下步骤:
父类用普通<class>标签定义即可
子类用<union-subclass>标签定义,在定义union-subclass的时候,需要注意如下几点:
Union-subclass标签不再需要包含key标签(与joined-subclass不同)
Union-subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),
也可以与class标签平行。 当Union-subclass标签的定义与class标签平行的时候,需要在Union-subclass标签中,添加extends属性,里面的值是父类的全路径名称。
子类的其它属性,像普通类一样,定义在Union-subclass标签的内部。这个时候,虽然在union-subclass里面定义的只有子类的属性,但是因为它继承了父类,所以,
不需要定义其它的属性,在映射到数据库表的时候,依然包含了父类的所有属性的映射字段。

!!!特别注意:在保存对象的时候,id不能重复(所以不能用自增方法生成主键)

2、存储和多态查询参见策略一:每棵类继承树对应一张表

 

这里我们将Animal定义为抽象类:

package com.lwf.hibernate.extend1;
//public  class Animal {
//public  class Animal {
//第三种策略的时候设为abstract来测试
public abstract 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;
	}
	
}

 

 

其它类相同.

映射文件:

<?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" abstract="true">
		<id name="id">
			<generator class="assigned"/>
		</id>
		<property name="name"/>
		<property name="sex"/>
		<union-subclass name="Pig" table="t_pig">
			<property name="weight"/>
		</union-subclass>
		<union-subclass name="Bird" table="t_bird">
			<property name="height"/>
		</union-subclass>
	</class>
</hibernate-mapping>	

 

注意文件中使用了,union-subclass,并且没有了key属性.

而且Animal的主键生成策略变成了assigned.

所以跟着我们的测试文件的save数据方法也要变.

测试类:

package com.lwf.hibernate.test;

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

import junit.framework.TestCase;

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 Ext3Test extends TestCase {
	
	/**
	 * 保存数据
	 *
	 */
	public void testSaveAnimal() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			session.beginTransaction();
			Pig p = new Pig();
			p.setId(1);
			p.setName("猪1");
			p.setSex(true);
			p.setWeight(400);
			
			Bird b = new Bird();
			b.setId(2);
			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 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 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 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 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 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 void testLoad6() {
		Session session = null;
		try {
			session = HibernateUtils.getSession();
			
			/**
			 * 多态查询
			 */
			List animalList = session.createQuery("from 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);
		}
	}
	
}

 

 

我们看看创建的表格:

 

mysql> desc t_bird;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id     | int(11)      | NO   | PRI |         |       |
| name   | varchar(255) | YES  |     | NULL    |       |
| sex    | bit(1)       | YES  |     | NULL    |       |
| height | int(11)      | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+
4 rows in set (0.03 sec)

mysql> desc t_pig;
+--------+--------------+------+-----+---------+-------+
| Field  | Type         | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+-------+
| id     | int(11)      | NO   | PRI |         |       |
| name   | varchar(255) | YES  |     | NULL    |       |
| sex    | bit(1)       | YES  |     | NULL    |       |
| weight | int(11)      | YES  |     | NULL    |       |
+--------+--------------+------+-----+---------+-------+

 你会发现因为父类为抽象类,所以并没有生成t_animal表,而子类中有了所有属性,生成的表中也有了所有的字段.这与前面二种策略是不同的.

你可能感兴趣的:(Hibernate,mysql,JUnit)