Hibernate-一对多OneToMany

例子:

  • 一个班级对应多个学生

  • 需要在班级端配置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语句总共执行三条:
  • 先插入班级,再分别插入两个学生
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值