博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate单表继承映射
阅读量:4291 次
发布时间:2019-05-27

本文共 5645 字,大约阅读时间需要 18 分钟。

实际开发中,有这么一种情况:有一个父类Person,它有两个子类:Teacher和Student都继承了Person ,如图:

我们可以把这种关系的数据,设计到一张表中展示,如图:

现在我们就来看一下,怎么样来写实体类和对应的映射关系来生成上面这张表,

新建一个java项目,结构如下:

jar和hibernate官网获取方法,请参见《》

Person代码:

package com.robert.pojo;public class Person {	private int id ;	private String name ;	private int age ;	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 int getAge() {		return age;	}	public void setAge(int age) {		this.age = age;	}	}

Student类代码:

package com.robert.pojo;public class Student extends Person {	private String work ;	public String getWork() {		return work;	}	public void setWork(String work) {		this.work = work;	}	}
Teacher类代码:

package com.robert.pojo;public class Teacher extends Person {	private int salary ;	public int getSalary() {		return salary;	}	public void setSalary(int salary) {		this.salary = salary;	}	}

Person.hbm.xml配置文件:

HibernateUtil代码:

package com.robert.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.cfg.Configuration;/** * hibernate工具类 */public class HibernateUtil {	private static Configuration cfg = null;	private static SessionFactory factory = null;	private static Session session = null ;		static {		init();	}	/**	 * 初始化获得Configuration和SessionFacroty对象	 */	public static void init() {		cfg = new Configuration().configure();		factory = cfg.buildSessionFactory(new StandardServiceRegistryBuilder()				.applySettings(cfg.getProperties()).build());	}	/**	 * 获得Session对象	 * @return	 */	public static Session getSession() {		if (factory != null){			return session = factory.openSession();		}				init();		return session = factory.openSession();	}		/**	 * 关闭Session	 */	public static void closeSession() {		if(session!=null && session.isOpen())			session.close();	}}
hibernate.cfg.xml代码:

com.mysql.jdbc.Driver
jdbc:mysql:///hibernate4
root
root
org.hibernate.dialect.MySQL5Dialect
true
true
update

HibernateTest代码:

package com.robert.test;import java.io.IOException;import java.sql.SQLException;import javax.sql.rowset.serial.SerialException;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.tool.hbm2ddl.SchemaExport;import org.junit.Test;import com.robert.pojo.Person;import com.robert.pojo.Student;import com.robert.pojo.Teacher;import com.robert.util.HibernateUtil;public class HibernateTest {	/**	 * 根据*.hbm.xml文件对应的生成数据库表	 */	@Test	public void testCreateDB() {		Configuration cfg = new Configuration().configure();		SchemaExport se = new SchemaExport(cfg);		// 第一个参数:是否生成ddl脚本		// 第二个参数:是否执行到数据库中		se.create(true, true);	}	/**	 * 保存数据	 * 	 * @throws HibernateException	 * @throws SerialException	 * @throws SQLException	 * @throws IOException	 */	@Test	public void testSave() throws HibernateException, SerialException,			SQLException, IOException {		Session session = null;		Transaction tx = null;		try {			session = HibernateUtil.getSession();			tx = session.beginTransaction();			Teacher t1 = new Teacher() ;			t1.setAge(32) ;			t1.setName("张老师") ;			t1.setSalary(5000) ;						Student stu1 = new Student() ;			stu1.setAge(22) ;			stu1.setName("王同学") ;			stu1.setWork("家庭作业1") ;						Student stu2 = new Student() ;			stu2.setAge(24) ;			stu2.setName("刘同学") ;			stu2.setWork("housework") ;						session.save(t1) ;			session.save(stu1) ;			session.save(stu2) ;						tx.commit();		} catch (HibernateException e) {			if (tx != null) {				tx.rollback();			}			e.printStackTrace();			throw e;		} finally {			HibernateUtil.closeSession();		}	}	/**	 * get获取数据	 */	@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("name="+person.getName());						//session的get方法得到的person是他的子类			//但是load方法得到的是子类的代理类,所以load方法,不可以使用instanceof方法判断类型			if(person instanceof Student) {				Student stu = (Student) person ;				System.out.println("work="+stu.getWork());			}						// 取数据			tx.commit();		} catch (Exception e) {			tx.rollback();			e.printStackTrace();		} finally {			HibernateUtil.closeSession();		}	}		/**	 * load获取数据	 */	@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("name="+person.getName());						//session的get方法得到的person是他的子类			//但是load方法得到的是子类的代理类,所以load方法,不可以使用instanceof方法判断类型//			if(person instanceof Student) {//				Student stu = (Student) person ;//				System.out.println("work="+stu.getWork());//			}						// 取数据			tx.commit();		} catch (Exception e) {			tx.rollback();			e.printStackTrace();		} finally {			HibernateUtil.closeSession();		}	}}

关于session的get和load方法返回的类型和代理问题,如图:

get方法返回的是真正的类

laod方法返回的是代理类

保存后数据库数据为:

测试自己测试即可,我就不贴测试结果过程和图了

总结:

1、在单表继承映射中,hibernate通过鉴别器来识别子类的类型,鉴别器由hibernate来经行维护。

2、查询数据时,如果使用get查询得到的数据类型可以经行多态判断;如果使用load查询,load是懒加载(lazy),返回的是代理类。

3、Person.hbm.xml中子类的配置还有一种形式:

就是将subclass放到class外面,使用extends属性,来继承class

如图:

你可能感兴趣的文章
Velocity初探小结--velocity使用语法详解
查看>>
设计模式学习 - Singleton Pattern
查看>>
学习Spring——依赖注入
查看>>
CSS3 transform 属性详解
查看>>
Java对象内存结构及大小计算
查看>>
Spring MVC注解的一些案列
查看>>
Web大文件断点续传,快来看看吧!
查看>>
javascript高级编程3第二章:在html中使用javascript
查看>>
Android中热修复框架AndFix原理解析及案例使用
查看>>
手写代码实现EventBus
查看>>
关于JSON的相关知识
查看>>
SpringMVC基础_常用注解
查看>>
Spring框架-IOC容器和Bean的配置(1)
查看>>
查询内容在网页里面分页显示+跳页查看
查看>>
mysql substring函数截取值后赋给一个declare变量
查看>>
Java Thread 的 sleep() 和 wait() 的区别
查看>>
DbUtils入门
查看>>
每一个程序员需要了解的10个Linux命令
查看>>
service的自调用 VS service之间调用
查看>>
Android权限管理之Permission权限机制及使用
查看>>