Hibernate表的映射关系

编写组合主键的类,该类必须实现Serializable接口,生成对应的get/set方法;最好实现equals和hashCode方法

单向多对一映射

这里是学生和班级的关系来解释

pojo

  • Student
public class Student {
	private int id;
	private String name;
	private int age;
	private Grade grade;
//get…set
}
  • Grade(班级)
public class Grade {
	private int id;
	private String name;
	//get…set
}

配置文件

  • Student.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Student">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<property name="age"/>
   <!-- 多对一  name 表示属性名  class 指明 属性对应的类 
		 column指 数据库表中的列名 -->
   <many-to-one name="grade" class="Grade" 
		column="grade_id" foreign-key="fk_grade" not-null="true"/>	
</class>
</hibernate-mapping>

单向一对多的关系映射

pojo

  • Student
public class Student {
	private int id;
	private String name;
	private int age;
//get…set
}
  • Grade:
public class Grade {
	private int id;
	private String name;
	private Set<Student> students = new HashSet<Student>(0);	//get…set
}

配置文件

  • Grade.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Grade">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<!-- set是 Grade中的集合属性  name属性名称 -->
		<set name="students">
			<!-- key表示外键  column外键列名-->
			<key column="grade_id" not-null="true"></key>
			<!-- one-to-many 一对多  类Grade 中  students 所表示类型 -->
			<one-to-many class="Student"/>
		</set>
	</class>
</hibernate-mapping>

测试

@Test
	public void testSave() throws Exception{
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			Grade grade = new Grade();
			grade.setName("基础");
			
			Student stu = new Student();
			stu.setName("张三疯");
			stu.setAge(22);
			Student stu1 = new Student();
			stu1.setName("老王");
			stu1.setAge(23);
			//关联
			grade.getStudents().add(stu);
			grade.getStudents().add(stu1);
			//保存数据的顺序 是根据外键的配置来决定的
			//如果外键不能为null,那么先保存一的一端
			//如果外键可以为null,则可以随意保存
			session.save(grade);
			session.save(stu);
			session.save(stu1);
			
			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();
			//取数据
			Grade grade = (Grade)session.get(Grade.class, 1);
			System.out.println("gradeName="+grade.getName());
			System.out.println("grade所对应的多的一端的数据");
			Iterator<Student> iter = grade.getStudents().iterator();
			for(;iter.hasNext();){
				Student temp = iter.next();
				System.out.println("name="+temp.getName()+"\tage="+temp.getAge());
			}
			tx.commit();
		}catch (HibernateException e) {
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
			throw e;
		}finally{
			HibernateUtil.closeSession();
		}
	}

双向一对多的关系映射

pojo

  • Student:
public class Student {
	private int id;
	private String name;
	private int age;
	private Grade grade;
//get…set
}
  • Grade:
public class Grade {
	private int id;
	private String name;
	private Set<Student> students = new HashSet<Student>(0);	//get…set
}

映射文件

  • Grade.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Grade">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<!-- set是 Grade中的集合属性  name属性名称 -->
		<set name="students">
			<!-- key表示外键  column外键列名-->
			<key column="grade_id"></key>
			<!-- one-to-many 一对多  类Grade 中  students 所表示类型 -->
			<one-to-many class="Student"/>
		</set>
	</class>
</hibernate-mapping>
  • Student.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Student">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<many-to-one name="grade" class="Grade" column="grade_id" not-null="true"></many-to-one>
	</class>
</hibernate-mapping>

测试代码

	@Test
	public void testGet(){
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			//取数据
			Grade grade = (Grade)session.get(Grade.class, 2);
			System.out.println("gradeName="+grade.getName());
			System.out.println("grade所对应的多的一端的数据");
			Iterator<Student> iter = grade.getStudents().iterator();
			for(;iter.hasNext();){
				Student temp = iter.next();
				System.out.println("name="+temp.getName()+"\tage="+temp.getAge());
			}
			System.out.println("========================");
			Student stu = (Student)session.get(Student.class, 1);
			System.out.println("studentname="+stu.getName()+"   gradeName="+stu.getGrade().getName());
			tx.commit();
		}catch (HibernateException e) {
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
			throw e;
		}finally{
			HibernateUtil.closeSession();
		}
	}

总结:在双向的一对多关联映射中,注意一的一端的配置:中不用指定非空not-null;
如果想要一的一端来维护关系,那么在多的一端不用指定关联列非空。

  • 级联操作cascade及inverse:

    1、cascade时级联操作,使得在操作一端数据时,可以级联操作被关联的另外一端的数据。
    2、在多对一的关系中,多的一端不能操作级联为delete。一般在多的一端设为save-update.
    3、在一对多的关系中,如果一的一端设置为delete时,多的一端不能指明外键为非空。
    4、Inverse设置关系维护方。当inverse=”false”时,谁管理关系谁维护。如果都管理了,那么都维护。当关系由多的一端来维护时,效率较高。当关系由一的一端来维护时。会多执行update语句。
    5、Inverse=”true”时,关系由另一端管理。不管一的一端是否指明关系,一的一端都不会去维护关系。都由多的一端负责。建议inverse=”true”.

基于外键单向一对一关联映射

  • Person:
public class Person {
	private int id;
	private String name;
	private int age;
	private IdCard idCard;
//get…set
}
  • IdCard:
public class IdCard{
	private int id;
	private String code;
	//get…set
}

映射文件

  • person.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Student">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<!-- 多对一  name 表示属性名  class 指明 属性对应的类 
		 column指 数据库表中的列名 -->
			<many-to-one name="grade" class="Grade" 
		column="grade_id" foreign-key="fk_grade" not-null="true" unique="true"/>	
</class>
</hibernate-mapping>

基于外键双向一对一关联映射

  • Person:
public class Person {
	private int id;
	private String name;
	private int age;
	private IdCard idCard;
//get…set
}
  • IdCard:
public class IdCard{
	private int id;
	private String code;
   private Person person;

	//get…set
}

映射文件

  • IdCard.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="IdCard">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="code"/>
		<one-to-one name="person" property-ref="idCard"/>
	</class>
</hibernate-mapping>
  • person.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Student">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<!-- 多对一  name 表示属性名  class 指明 属性对应的类 
		 column指 数据库表中的列名 -->
			<many-to-one name="grade" class="Grade" 
		column="grade_id" foreign-key="fk_grade" not-null="true" unique="true"/>	
</class>
</hibernate-mapping>

测试代码

	@Test
	public void testGet(){
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			Person person = (Person)session.get(Person.class, 1);
			System.out.println("personName="+person.getName()+"---IdCard:"+person.getIdCard().getCode());
			System.out.println("=======================================");
			IdCard idCard = (IdCard)session.get(IdCard.class, 2);
			System.out.println("personName="+idCard.getPerson().getName()+"--Idcard:"+idCard.getCode());
			//取数据
			tx.commit();
		}catch (HibernateException e) {
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
			throw e;
		}finally{
			HibernateUtil.closeSession();
		}
	}

基于主键单向一对一的单向关系映射

  • Person:
public class Person {
	private int id;
	private String name;
	private int age;
	private IdCard idCard;
//get…set
}
  • IdCard:
public class IdCard{
	private int id;
	private String code;
	//get…set
}

映射文件

  • IdCard.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Grade">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="code"/>
	</class>
</hibernate-mapping>
  • person.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Person">
		<id name="id">
			<!-- foreign表示引用外键 -->
			<generator class="foreign">
				<!-- 引用idCard属性所对应的主键 -->
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<!-- 一对一 -->
		<one-to-one name="idCard" constrained="true" cascade="save-update"/>
	</class>
</hibernate-mapping>

基于主键双向一对一映射关系

  • Person:
public class Person {
	private int id;
	private String name;
	private int age;
	private IdCard idCard;
//get…set
}
  • IdCard:
public class IdCard{
	private int id;
	private String code;
    private Person person;

	//get…set
}

映射文件

  • IdCard.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="IdCard">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="code"/>
		<one-to-one name="person"/>
	</class>
</hibernate-mapping>
  • person.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Person">
		<id name="id">
			<!-- foreign表示引用外键 -->
			<generator class="foreign">
				<!-- 引用idCard属性所对应的主键 -->
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<!-- 一对一 -->
		<one-to-one name="idCard" constrained="true" cascade="save-update"/>
	</class>
</hibernate-mapping>

基于主键单向多对多的关联映射

  • Role:
public class Role {
	private int id;
	private String name;
	private Set<Function> functions = new HashSet<Function>(0);
	//get…set

}
  • Function:
public class Function {
	private int id;
	private String name;
	private String code;
	private String url;
	public Function() {
		// TODO Auto-generated constructor stub
	}
	public Function(String name, String code, String url) {
		super();
		this.name = name;
		this.code = code;
		this.url = url;
	}

	//get…set }

映射文件

  • Role.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Role">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<!-- 多对多 -->
		<set name="functions" table="role_func" cascade="save-update">
			<!-- 表示当前类 映射到关系表中的列-->
			<key column="rid"/>
			<!-- 所对应的另一方在关系表中的列 -->
			<many-to-many column="fid" class="Function"/>
		</set>
	</class>
</hibernate-mapping>
  • function.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Function">
		<id name="id">
			<!-- foreign表示引用外键 -->
			<generator class="native"/>
		</id>
		<property name="name"/>
		<property name="code"/>
		<property name="url"/>
	</class>
</hibernate-mapping>

基于主键的双向多对多的关联映射

  • Role:
public class Role {
	private int id;
	private String name;
	private Set<Function> functions = new HashSet<Function>(0);
	//get…set

}
  • Function:
public class Function {
	private int id;
	private String name;
	private String code;
	private String url;
	private Set<Role> roles = new HashSet<Role>(0);

	public Function() {
		// TODO Auto-generated constructor stub
	}
	public Function(String name, String code, String url) {
		super();
		this.name = name;
		this.code = code;
		this.url = url;
	}

	//get…set }

映射文件

  • Role.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Role">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<!-- 多对多 -->
		<set name="functions" table="role_func" cascade="save-update">
			<!-- 表示当前类 映射到关系表中的列-->
			<key column="rid"/>
			<!-- 所对应的另一方在关系表中的列 -->
			<many-to-many column="fid" class="Function"/>
		</set>
	</class>
</hibernate-mapping>
  • function.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Function">
		<id name="id">
			<!-- foreign表示引用外键 -->
			<generator class="native"/>
		</id>
		<property name="name"/>
		<property name="code"/>
		<property name="url"/>
<set name="roles" table="role_func" inverse="true">
			<key column="fid"/>
			<many-to-many column="rid" class="Role"/>
		</set>
	</class>
</hibernate-mapping>

测试代码

	@Test
	public void testGet(){
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			Role role = (Role)session.get(Role.class, 1);
			System.out.println("角色名:"+role.getName());
			System.out.println("该角色所对应的权限:");
			for(Iterator<Function> iter = role.getFunctions().iterator();
					iter.hasNext();){
				Function func = iter.next();
				System.out.println(func.getName()+"---"+func.getCode());
			}
			//取数据
			tx.commit();
		}catch (HibernateException e) {
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
			throw e;
		}finally{
			HibernateUtil.closeSession();
		}
	}

List(基于集合映射)

  • javabean
public class Grade {
	private int id;
	private String name;
	private List<Student> students = new ArrayList<Student>(0);
	}
  • 映射文件
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Grade">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<list name="students" cascade="all">
			<!-- key表示外键  column外键列名-->
			<key column="grade_id"></key>
			<!-- 在多的一端 产生一列 用来表示顺序 如果不指明列名 默认为 idx 
				值由hibernate来维护
			 -->
			<list-index column="sort">
			</list-index>
			<!-- one-to-many 一对多  类Grade 中  students 所表示类型 -->
			<one-to-many class="Student"/>
		</list>
	</class>
  • 测试文件
@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();
			Grade grade = new Grade();
			grade.setName("基础");
			
			Student stu = new Student();
			stu.setName("张三疯");
			stu.setAge(22);
			Student stu1 = new Student();
			stu1.setName("老王");
			stu1.setAge(23);
			Student stu2 = new Student();
			stu2.setName("老李");
			stu2.setAge(23);
			//关联
			grade.getStudents().add(stu);
			grade.getStudents().add(stu1);
			grade.getStudents().add(stu2);
			//保存数据的顺序 是根据外键的配置来决定的
			//如果外键不能为null,那么先保存一的一端
			//如果外键可以为null,则可以随意保存
			session.save(grade);
			session.save(stu);
			session.save(stu1);
			session.save(stu2);
			
			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();
			//取数据
			Grade grade = (Grade)session.get(Grade.class, 1);
			System.out.println("gradeName="+grade.getName());
			System.out.println("grade所对应的多的一端的数据");
			List<Student> list = grade.getStudents();
			for(Student stu:list){
				System.out.println(stu.getName());
			}
			tx.commit();
		}catch (HibernateException e) {
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
			throw e;
		}finally{
			HibernateUtil.closeSession();
		}
	}

基于map集合映射

  • javabean
public class Grade {
	private int id;
	private String name;
	private Map<String,Student> students = new HashMap<String,Student>(0);
	
}
  • 映射文件
<hibernate-mapping package="cn.siggy.pojo">
	<class name="Grade">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<map name="students" cascade="all">
			<!-- key表示外键 -->
			<key column="grade_id"/>
			<!-- map-key是映射为map集合时,对应key值  key值 建议为唯一 -->
			<map-key type="string" column="name"/>
			<one-to-many class="Student"/>
		</map>
	</class>
</hibernate-mapping>
  • 测试
@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();
			Grade grade = new Grade();
			grade.setName("基础");
			
			Student stu = new Student();
			stu.setName("张三疯");
			stu.setAge(22);
			Student stu1 = new Student();
			stu1.setName("老王");
			stu1.setAge(23);
			Student stu2 = new Student();
			stu2.setName("老李");
			stu2.setAge(23);
			//关联
			grade.getStudents().add(stu);
			grade.getStudents().add(stu1);
			grade.getStudents().add(stu2);
			//保存数据的顺序 是根据外键的配置来决定的
			//如果外键不能为null,那么先保存一的一端
			//如果外键可以为null,则可以随意保存
			session.save(grade);
			session.save(stu);
			session.save(stu1);
			session.save(stu2);
			
			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();
			//取数据
			Grade grade = (Grade)session.get(Grade.class, 1);
			System.out.println("gradeName="+grade.getName());
			System.out.println("grade所对应的多的一端的数据");
			Map<String,Student> map = grade.getStudents();
			System.out.println(map.get("老王").getAge());
			tx.commit();
		}catch (HibernateException e) {
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
			throw e;
		}finally{
			HibernateUtil.closeSession();
		}
	}

基于一张表的继承映射

  • person
public class Person {
	private int id;
	private String name;
	private int age;
}
  • student
public class Student extends Person{
	private String work;
}
  • Teacher
public class Teacher extends Person{
	private int salary;
}

映射文件(person)

<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"/>
		<subclass name="Student" discriminator-value="s">
			<property name="work"/>
		</subclass>
		<subclass name="Teacher" discriminator-value="t">
			<property name="salary"/>
		</subclass>
		
	</class>
</hibernate-mapping>

测试

@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();
		}
	}

总结:
1、在单表继承映射中,hibernate通过鉴别器来识别之类的类型。鉴别器由hibernate来进行维护。
2、查询数据时,如果使用get查询得到的数据类型可以进行多态判断。如果是通过load(lazy)查询,不能判断。

基于每个具体类一张表的继承映射

  • Person类
public class Person {
	private int id;
	private String name;
	private int age;
}
  • Student类
public class Student extends Person{
	private String work;
}
  • Teacher类
public class Teacher extends Person{
	private int salary;
}

Person.hbm.xml文件

<hibernate-mapping package="cn.siggy.pojo">
	<class name="Person" abstract="true">
		<id name="id" column="id">
			<generator class="assigned"></generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<union-subclass name="Student">
			<property name="work"/>
		</union-subclass>
		<union-subclass name="Teacher">
			<property name="salary"/>
		</union-subclass>
	</class>
</hibernate-mapping>

测试

@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.setId(1);
			teacher.setName("siggy");
			teacher.setAge(26);
			teacher.setSalary(5000);
			Student student = new Student();
			student.setId(2);
			student.setName("小明");
			student.setAge(22);
			student.setWork("hello world");
			Student student1 = new Student();
			student1.setId(3);
			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();
		}
	}

总结:
1、在每个具体类一张表的继承映射中,主键的生成不能使用identity。建议使用uuid,sequence,assigned等。
2、数据表的结构更加合理。多态查询效率不高

基于每个类一张表的继承映射

pojo

  • Person类
public class Person {
	private int id;
	private String name;
	private int age;
}
  • Student类
public class Student extends Person{
	private String work;
}
  • Teacher类
public class Teacher extends Person{
	private int salary;
}

Person.hbm.xml文件

<hibernate-mapping package="cn.siggy.pojo">
	<class name="Person">
		<id name="id" column="id">
			<generator class="assigned"></generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<joined-subclass name="Teacher">
			<key column="id"/>
			<property name="salary"/>
		</joined-subclass>
		<joined-subclass name="Student">
			<key column="id"/>
			<property name="work"/>
		</joined-subclass>
	</class>
</hibernate-mapping>

测试

@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();
		}
	}

总结:
3种继承映射比较:
所有存1张表,数据冗余比较多。效率比较高。推荐使用。
每个子类一张表。数据冗余比较少,查询效率低,主键不能自增。需要指明为assigned,uuid,hilo等
每个类一张表。数据冗余比较少。查询效率比每个子类一张表稍高。维护的表的个数多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值