【HibernateHibernate实体关系映射——双边的多对一、一对多关系


双边的多对一、一对多关系

 

     双边关系是最常见的配置。在多方有一方的引用,一方也有多方的引用。双边关系能够很方便的查询数据。下面以一个班级与学生的双边关系来深入学习。

 

     班级(clazz类)与学生(student类)为一对多关系。班级中有学生属性,学生中有班级属性,二者是双边的关系。

 

具体代码如下:

 

Clazz类中有一个id主键和一个name属性,另外还有一个List类型的集合属性,代表该班级内的学生。班级与学生的关系是一对多关系,这里使用了@OneToMany配置,并用mappedBy属性配置与该List属性对应的是Student类中的clazz属性。

 

Clazz.java

 

package com.lmb.hibernate.bean;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.*;

@Entity
@Table(name="tb_clazz")
public class Clazz {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;
	private String name;
	
	@OneToMany(mappedBy = "clazz")
	private List students = new ArrayList();

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List getStudents() {
		return students;
	}
	public void setStudents(List students) {
		this.students = students;
	}
}


 

    双边关系中,控制权一般交给多方,因此这里的@OneToMany没有哦诶之数据库的外键列,而只配置了一个mappedBy属性,值为clazz,告诉hibernate,配置信息要到Student类的clazz属性中找。

 

  Student类中有一个id主键以及name姓名、sex性别两个普通属性,还有一个Clazz类型的属性clazz,代表所在的班级。该属性与Clazz中的List集合属性是对应的。从逻辑上来讲,某student的clazz属性为某clazz,该clazz的List中必定还有改student。配置了mappedBy后,hibernate能自动维护这种关系。

 

   Student与Clazz是一对多的关系,一对多使用@ManyToOne配置,另外用@JoinColumn配置关联的列名。这里用tb_student表的class_id列于tb_class的id主键列连接。这里同时配置了级联保存类型为PERSIST,创建student时,会自动将clazz也写进数据库。

 

student.java

 

package com.lmb.hibernate.bean;

import javax.persistence.*;

@Entity
@Table(name="tb_student")
public class Student {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Integer id;
	private String name;
	private String sex;

	@ManyToOne(
		cascade = {
			CascadeType.PERSIST
		},
		fetch = FetchType.EAGER
	)
	@JoinColumn(name="class_id")
	private Clazz clazz;

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Clazz getClazz() {
		return clazz;
	}
	public void setClazz(Clazz clazz) {
		this.clazz = clazz;
	}
}


注意:@JoinColumn配置了外键列,这里把控制权交给了多方,也可以交给一方。当一方控制时,一方的配置同单边的一对多关系配置完全相同。

 

    将Clazz与Studet实体类配置到hibernate配置文件中去。

 

hibernate.cfg.xml

 






    
        org.hibernate.dialect.MySQLDialect
        jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8
        lmb
        lmb
        com.mysql.jdbc.Driver
        
        
        
        
        
    
    


 

    双边关系使用起来比较方便,查询或者使用时可以从任意一方访问到另一方。不过双边关系也不是任何时候都适用的。如果多方的数据量比较大,比如几千条几万条,设置一方的一对多映射可能是个隐患。比如,不小心执行了getStudent().size(),程序会加载这几千条几万条的子数据,造成巨大的IO开支,影响到程序的运行效率。这种情况下设置双边关系是不明智的,应该取消一方的一对多映射,不要使用getStudent().size()来统计子数据,而改用执行select count(s) from Student s查询语句的方式统计个数。

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(框架,Hibernate,大话Hibernate,Hibernate实体关系映射,双边的多对一一对多关系)