例子:
-
一个班级对应多个学生
-
需要在班级端配置OneToMany。
-
一对多:一的一方用se接口集合,不能用HashSet,因为Hibernate有自己的set实现。
-
set与list区别:set无序,set不重复
以下两种方法建出来表结构都一样(如下),但在性能方面不一样,建议用第二种。
方法一:由班级表维护学生表的外键
班级表:
public class Clazz {
private int id;
private String name;
private Set<Student> students;
//get、set省略
}
Clazz.hbm.xml
- 学生表:
public class Student {
private int id;
private String name;
private double score;
//get、set省略
}
Student.hbm.xml
- 生成表如下图
- 添加数据
public void testAdd(){
Student s1 = new Student();
s1.setName("Tom");
s1.setScore(80);
Student s2 = new Student();
s2.setName("Jack");
s2.setScore(90);
Set<Student> set = new HashSet<Student>();
set.add(s1);
set.add(s2);
Clazz clazz= new Clazz();
clazz.setName("ZY131");
clazz.setStudents(set);
Session session =null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
//先插入学生,再插入班级,否则会报瞬态异常
session.save(s1);
session.save(s2);
session.save(clazz);
session.getTransaction().commit();
}catch(Exception e){
session.getTransaction().rollback();
e.printStackTrace();
}finally{
HibernateUtil.closeSession(session);
}
}
- 结果
Hibernate插入执行sql语句分析
- 总共执行5次sql语句:
- 1、先分别插入第一个学生和第二个学生的name和score,clazz_id此时为空。
- 2、插入班级的信息
- 3、分别插入学生表的clazz_id
load查询数据
public void testLoad(){
Clazz c = new Clazz();
Session session =null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
c = (Clazz)session.load(Clazz.class, 1);
System.out.println("Clazz Name:"+c.getName());
//如果没有执行for循环,就不会到学生表根据班级查询学生表名字了
for(Student s:c.getStudents()){
System.out.println("Student Name:"+s.getName());
}
session.getTransaction().commit();
}catch(Exception e){
session.getTransaction().rollback();
e.printStackTrace();
}finally{
HibernateUtil.closeSession(session);
}
}
代码分析
- 如果没有执行for循环,就不会到学生表根据班级查询学生表名字了
所以虽然Hibernate再连表操作时可能会执行多条语句,但查询的话不一定性能降低。
方法二:由学生表维护学生表的外键
- 班级表
public class Clazz {
private int id;
private String name;
private Set<Student> students;
//get、set省略
}
Clazz.hbm.xml
- 学生表
public class Student {
private int id;
private String name;
private double score;
private Clazz clazz;
//get、set省略
}
Student.hbm.xml
- 添加操作
public void testAdd(){
Student s1 = new Student();
s1.setName("Tom");
s1.setScore(80);
Student s2 = new Student();
s2.setName("Jack");
s2.setScore(90);
Clazz clazz= new Clazz();
clazz.setName("ZY131");
s1.setClazz(clazz);
s2.setClazz(clazz);
Session session =null;
try{
session = HibernateUtil.getSession();
session.beginTransaction();
//先保存班级,再保存学生
session.save(clazz);
session.save(s1);
session.save(s2);
session.getTransaction().commit();
}catch(Exception e){
session.getTransaction().rollback();
e.printStackTrace();
}finally{
HibernateUtil.closeSession(session);
}
}
- 结果与前面一样
Hibernate执行语句分析:比第一种少了两条,性能更快
- sql语句总共执行三条:
- 先插入班级,再分别插入两个学生