Hibernate懒加载急加载我们需要注意的问题
2017-12-28 10:41
423 查看
1、显而易见的概念
懒加载——也被称为延迟加载,它在查询的时候不会立刻访问数据库,而是返回代理对象,当真正去使用对象的时候才会访问数据库。
急加载——就是只要我们实体做了关联,全部一次性执行完所有的SQL语句
2、@OneToMany
懒加载结果:
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
曹操
刘备
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
孙权
急加载结果
Hibernate: select teacherent0_.t_id as t_id1_5_, teacherent0_.t_name as t_name2_5_ from t_teacher2 teacherent0_
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
曹操
刘备
孙权
@ManyToOne
Hibernate: select studentent0_.s_id as s_id1_4_, studentent0_.s_name as s_name2_4_, studentent0_.tid as tid3_4_ from t_student2 studentent0_
曹操
Hibernate: select teacherent0_.t_id as t_id1_5_0_, teacherent0_.t_name as t_name2_5_0_, stulist1_.tid as tid3_4_1_, stulist1_.s_id as s_id1_4_1_, stulist1_.s_id as s_id1_4_2_, stulist1_.s_name as s_name2_4_2_, stulist1_.tid as tid3_4_2_ from t_teacher2 teacherent0_ left outer join t_student2 stulist1_ on teacherent0_.t_id=stulist1_.tid where teacherent0_.t_id=?
陈老师
刘备
陈老师
孙权
Hibernate: select teacherent0_.t_id as t_id1_5_0_, teacherent0_.t_name as t_name2_5_0_, stulist1_.tid as tid3_4_1_, stulist1_.s_id as s_id1_4_1_, stulist1_.s_id as s_id1_4_2_, stulist1_.s_name as s_name2_4_2_, stulist1_.tid as tid3_4_2_ from t_teacher2 teacherent0_ left outer join t_student2 stulist1_ on teacherent0_.t_id=stulist1_.tid where teacherent0_.t_id=?
张老师
改进代码:
输出结果:
Hibernate: select teacherent1_.t_name as col_0_0_, studentent0_.s_name as col_1_0_ from t_student2 studentent0_ left outer join t_teacher2 teacherent1_ on studentent0_.tid=teacherent1_.t_id
曹操/陈老师
刘备/陈老师
孙权/张老师
看你以上代码该给个了结的时候了。
1、急加载,在多对一的情况下默认是急加载,也就是查询多会一次性把一的一方全部查询出来。如果我们不想现在用关联对象里面的属性,可以选择懒加载。急加载会先查询出主对象然后根据主对象执行N条语句查询出关联对象。SQL会出现1+N查询的情况。
2、懒加载,在一对多的情况下默认是懒加载,不去运用关联对象属性时,不会进行SQL查询。但是如果是循环查询关联对象会出现调用一个属性执行一条SQL语句的情况,上面代码已经充分说明。如果不对关联对象进行循环查询不会出现N+1的情况,我相信大家也不会用懒加载时候,同一时间去查询出关联对象。
3、如果我们想同一时间查询出所有关联对象,而希望SQL语句不会出现N+1的悲剧发生,建议大家运用关联查询,把查询后的结果封装到自定义的DTO对象中。DTO作为数据传输对象可以传输到任何对象中去,当然包括VO.
懒加载——也被称为延迟加载,它在查询的时候不会立刻访问数据库,而是返回代理对象,当真正去使用对象的时候才会访问数据库。
急加载——就是只要我们实体做了关联,全部一次性执行完所有的SQL语句
2、@OneToMany
****默认为懒加载****
@Test public void find(){ Session s= sessionFactory.openSession(); List<TeacherEntity> teacher= s.createQuery("from TeacherEntity").list(); for(TeacherEntity t:teacher){ t.getTname(); List<StudentEntity> lists= t.getStuList(); for(StudentEntity stu:lists){ System.out.println(stu.getSname()); } } s.close(); }
懒加载结果:
Hibernate: select teacherent0_.t_id as t_id1_5_, teacherent0_.t_name as t_name2_5_ from t_teacher2 teacherent0_
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
曹操
刘备
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
孙权
急加载结果
Hibernate: select teacherent0_.t_id as t_id1_5_, teacherent0_.t_name as t_name2_5_ from t_teacher2 teacherent0_
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
Hibernate: select stulist0_.tid as tid3_4_0_, stulist0_.s_id as s_id1_4_0_, stulist0_.s_id as s_id1_4_1_, stulist0_.s_name as s_name2_4_1_, stulist0_.tid as tid3_4_1_ from t_student2 stulist0_ where stulist0_.tid=?
曹操
刘备
孙权
@ManyToOne
**默认为急加载**
@Test public void findManyToOne(){ //获得session Session s= sessionFactory.openSession(); String hql="from StudentEntity"; List<StudentEntity> list=s.createQuery(hql).list(); for(StudentEntity stu:list){ System.out.println(stu.getSname()); } } **急加载结果:** Hibernate: select studentent0_.s_id as s_id1_4_, studentent0_.s_name as s_name2_4_, studentent0_.tid as tid3_4_ from t_student2 studentent0_ Hibernate: select teacherent0_.t_id as t_id1_5_0_, teacherent0_.t_name as t_name2_5_0_, stulist1_.tid as tid3_4_1_, stulist1_.s_id as s_id1_4_1_, stulist1_.s_id as s_id1_4_2_, stulist1_.s_name as s_name2_4_2_, stulist1_.tid as tid3_4_2_ from t_teacher2 teacherent0_ left outer join t_student2 stulist1_ on teacherent0_.t_id=stulist1_.tid where teacherent0_.t_id=? Hibernate: select teacherent0_.t_id as t_id1_5_0_, teacherent0_.t_name as t_name2_5_0_, stulist1_.tid as tid3_4_1_, stulist1_.s_id as s_id1_4_1_, stulist1_.s_id as s_id1_4_2_, stulist1_.s_name as s_name2_4_2_, stulist1_.tid as tid3_4_2_ from t_teacher2 teacherent0_ left outer join t_student2 stulist1_ on teacherent0_.t_id=stulist1_.tid where teacherent0_.t_id=? 曹操 刘备 孙权 **懒加载结果:** Hibernate: select studentent0_.s_id as s_id1_4_, studentent0_.s_name as s_name2_4_, studentent0_.tid as tid3_4_ from t_student2 studentent0_ 曹操 刘备 ****修改代码,循环获取关联对象(One一方)**** ` @Test public void findManyToOne(){ //获得session Session s=sessionFactory.openSession(); String hql="from StudentEntity"; List<StudentEntity> list=s.createQuery(hql).list(); for(StudentEntity stu:list){ System.out.println(stu.getSname()); //获取one方值 System.out.println(stu.getTeacher().getTname()); } } **结果如下:**
Hibernate: select studentent0_.s_id as s_id1_4_, studentent0_.s_name as s_name2_4_, studentent0_.tid as tid3_4_ from t_student2 studentent0_
曹操
Hibernate: select teacherent0_.t_id as t_id1_5_0_, teacherent0_.t_name as t_name2_5_0_, stulist1_.tid as tid3_4_1_, stulist1_.s_id as s_id1_4_1_, stulist1_.s_id as s_id1_4_2_, stulist1_.s_name as s_name2_4_2_, stulist1_.tid as tid3_4_2_ from t_teacher2 teacherent0_ left outer join t_student2 stulist1_ on teacherent0_.t_id=stulist1_.tid where teacherent0_.t_id=?
陈老师
刘备
陈老师
孙权
Hibernate: select teacherent0_.t_id as t_id1_5_0_, teacherent0_.t_name as t_name2_5_0_, stulist1_.tid as tid3_4_1_, stulist1_.s_id as s_id1_4_1_, stulist1_.s_id as s_id1_4_2_, stulist1_.s_name as s_name2_4_2_, stulist1_.tid as tid3_4_2_ from t_teacher2 teacherent0_ left outer join t_student2 stulist1_ on teacherent0_.t_id=stulist1_.tid where teacherent0_.t_id=?
张老师
改进代码:
@Test public void findManyToOne(){ //获得session Session s=sessionFactory.openSession(); //关联查询 String hql="select new com.lovo.hibernate.manytoone.StuDto(t.tname,s.sname) from StudentEntity s left join s.teacher t "; //用DTO对象接收 List<StuDto> listObj=s.createQuery(hql).list(); //循环遍历出DTO的数据 for(StuDto dto:listObj){ System.out.println(dto.getSname()+"/"+dto.getTname()); } }
输出结果:
Hibernate: select teacherent1_.t_name as col_0_0_, studentent0_.s_name as col_1_0_ from t_student2 studentent0_ left outer join t_teacher2 teacherent1_ on studentent0_.tid=teacherent1_.t_id
曹操/陈老师
刘备/陈老师
孙权/张老师
看你以上代码该给个了结的时候了。
1、急加载,在多对一的情况下默认是急加载,也就是查询多会一次性把一的一方全部查询出来。如果我们不想现在用关联对象里面的属性,可以选择懒加载。急加载会先查询出主对象然后根据主对象执行N条语句查询出关联对象。SQL会出现1+N查询的情况。
2、懒加载,在一对多的情况下默认是懒加载,不去运用关联对象属性时,不会进行SQL查询。但是如果是循环查询关联对象会出现调用一个属性执行一条SQL语句的情况,上面代码已经充分说明。如果不对关联对象进行循环查询不会出现N+1的情况,我相信大家也不会用懒加载时候,同一时间去查询出关联对象。
3、如果我们想同一时间查询出所有关联对象,而希望SQL语句不会出现N+1的悲剧发生,建议大家运用关联查询,把查询后的结果封装到自定义的DTO对象中。DTO作为数据传输对象可以传输到任何对象中去,当然包括VO.
相关文章推荐
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- hibernate级联更新外键 需要注意的问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- Hibernate操作时间需要注意的问题
- hibernate3中如何获得到库表所有字段的名称;hibernate 与 jdbc 共存需要注意的问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- 项目问题总结二、hibernate和多线程同时使用需要注意
- Hibernate多对多双向关联需要注意的问题(实例说话)
- Hibernate操作时间需要注意的问题(转)
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- ttserver发现的问题,可能是故意这么弄的,如果不是故意的,那就需要我们注意了
- 畅谈seo接单时我们需要注意的三个问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- 使用OpenSessionInView解决懒加载需要注意的问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- flex application中预加载配置文件需要注意的问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题
- Hibernate使用二级缓存时,createSQLQuery需要注意的问题