4.测试代码 5.测试结果 1.执行tes ...">
1.子类和父类的关系图:
2.Person,Student和Teacher类
package cn.siggy.pojo; public class Person { private int id; private String name; private int age; /*get/set*/ } ------------------------------------------------------------------ package cn.siggy.pojo; public class Student extends Person{ private String work; public String getWork() { return work; } public void setWork(String work) { this.work = work; } } ------------------------------------------------------------------- package cn.siggy.pojo; public class Teacher extends Person{ private int salary; public int getSalary() { return salary; } public void setSalary(int salary) { this.salary = salary; } }
3.映射文件
Person.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="cn.siggy.pojo"> <class name="Person"> <id name="id" column="id"> <generator class="native"></generator> </id> <!-- 指明鉴别器 --> <discriminator column="type" type="string"/> <property name="name"/> <property name="age"/> </class> <subclass name="Student" discriminator-value="s" extends="Person"> <property name="work"/> </subclass> <subclass name="Teacher" discriminator-value="t" extends="Person"> <property name="salary"/> </subclass> </hibernate-mapping>
映射文件理解:
<!-- 指明鉴别器 -->
<discriminator column="type" type="string"/>
4.测试代码
package cn.siggy.test; import java.sql.SQLException; import javax.sql.rowset.serial.SerialException; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.Test; import cn.siggy.pojo.Person; import cn.siggy.pojo.Student; import cn.siggy.pojo.Teacher; import cn.siggy.util.HibernateUtil; public class HibernateTest { @Test public void testCreateDB(){ Configuration cfg = new Configuration().configure(); SchemaExport se = new SchemaExport(cfg); //第一个参数 是否生成ddl脚本 第二个参数 是否执行到数据库中 se.create(true, true); } @Test public void testSave() throws HibernateException, SerialException, SQLException{ Configuration cfg = new Configuration().configure(); SessionFactory factory = cfg.buildSessionFactory(new StandardServiceRegistryBuilder() .applySettings(cfg.getProperties()).build()); Session session = null; Transaction tx = null; try{ session = factory.openSession(); tx = session.beginTransaction(); Teacher teacher = new Teacher(); teacher.setName("siggy"); teacher.setAge(26); teacher.setSalary(5000); Student student = new Student(); student.setName("小明"); student.setAge(22); student.setWork("hello world"); Student student1 = new Student(); student1.setName("小强"); student1.setAge(20); student1.setWork("struts2"); session.save(student); session.save(student1); session.save(teacher); tx.commit(); }catch (HibernateException e) { if(tx!=null) tx.rollback(); e.printStackTrace(); throw e; }finally{ HibernateUtil.closeSession(); } } @Test public void testGet(){ Session session = null; Transaction tx = null; try{ session = HibernateUtil.getSession(); tx = session.beginTransaction(); Person person = (Person)session.get(Person.class, 2); System.out.println(person.getName()); if(person instanceof Student){ Student stu = (Student)person; System.out.println(stu.getWork()); } tx.commit(); }catch (HibernateException e) { if(tx!=null) tx.rollback(); e.printStackTrace(); throw e; }finally{ HibernateUtil.closeSession(); } } @Test public void testLoad(){ Session session = null; Transaction tx = null; try{ session = HibernateUtil.getSession(); tx = session.beginTransaction(); Person person = (Person)session.load(Person.class, 2); System.out.println(person.getName()); if(person instanceof Student){ Student stu = (Student)person; System.out.println(stu.getWork()); } tx.commit(); }catch (HibernateException e) { if(tx!=null) tx.rollback(); e.printStackTrace(); throw e; }finally{ HibernateUtil.closeSession(); } } }
5.测试结果
1.执行testSave()方法:
2.执行testGet()方法:【hibernate是通过鉴别器(即type字段)来判断对象是Student还Teacher的】
3.执行testLoad()方法:
【会出现类型转换错误,因为Load方式要在对象被使用时才加载,而加载前是一个动态代理类型,故而hibernate不知道它是Person或者Student还是Teacher】
备注:测试代码是可以运行的,因为运行一下代码时:
@Test public void testLoad(){ Session session = null; Transaction tx = null; try{ session = HibernateUtil.getSession(); tx = session.beginTransaction(); Person person = (Person)session.load(Person.class, 2); System.out.println(person.getName()); if(person instanceof Student){ Student stu = (Student)person; System.out.println(stu.getWork()); } tx.commit(); }catch (HibernateException e) { if(tx!=null) tx.rollback(); e.printStackTrace(); throw e; }finally{ HibernateUtil.closeSession(); } }System.out.println(person.getName());便已经使用了Person对象,故而Load开始加载Person表中的信息,再根据type字段,从而可以判断Person是Student还是Teacher对象
总结:
1、在单表继承映射中,hibernate通过鉴别器来识别之类的类型。鉴别器由hibernate来进行维护。
2、查询数据时,如果使用get查询得到的数据类型可以进行多态判断。如果是通过load(lazy)查询,不能判断。
原文:http://www.cnblogs.com/chxbar/p/6682319.html