什么是hibernate的N+1问题?先了解这样一个描述:

多个学生可以对应一个老师,所以student(n)---teacher(1)。Stu类中有一个属性teacher。在hibernate配置文件中,Stu.hbm.xml中这样配置teacher

<many-to-one name="teacher" class="com.ssh.shop.model.Account" lazy="false" >
<column name="tid"/> <!--相当于 外键 -->
</many-to-one>

上面的 lazy="false",表示级联查询关联对象,但是当使用session.query()执行查询Student后打印sql语句:

select * from student ...

select * from teacher where tid=?
select * from teacher where tid=?
select * from teacher where tid=?
  ...

查看sql发现,查了一条student语句,查了N条与stu关联的teacher语句。

配置里面,除了配置lazy之外,还有个配置是fetch,fetch有2个选项:select和join。当fetch=join时,会不会只查一条语句呢?答案是:不会。原因(后续补...)

所以,这里就出现了N+1的问题

N+1问题:执行一条select语句查询当前表,执行N条语句查询与当前表关联的表,N是不同的关联数。效率很差
  lazy:是否及时加载,false是及时加载
  fetch:以什么样的方式加载,select(默认):select语句查询;join:以join语句查询
注意:join在many-to-one中是无效的,在one-to-many中有效。
  A表===关联===>B表===关联===>C表...(关系多的话要一个表一个表的关联...)


所以,在任何情况下,都不要在xml中配置lazy="false" fetch="join"


N+1解决方案:
自己写hql语句,如加入 hql = "from Stu s left join fetch s.teacher where s.sex = :sex",
  left join代表左外连接,fetch代表把查出来的s.teacher抓取到Category对象中。

  如果不写fetch,则executeQuery这条hql语句,会得到一个对象数组 [Student[id,name,sex...] ,Teacher[id,name,...] ]  (可以自己debug查看执行结果)

对应的sql语句如下:

select s.* , t.*
  from
student s left outer join teacher t
  on s.tid=t.id
  where s.sex = '男'

如果不写hql,而又配置了many-to-one,则默认为懒加载关联,lazy="true",抛异常:
  org.hibernate.LazyInitializationException: could not initialize proxy - no Session
因为session在加载Stu后关闭,再去加载对应的关联teacher的时候,session已经关闭了。

Hibernate之N+1问题的更多相关文章

  1. hibernate多对多关联映射

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  2. 解决 Springboot Unable to build Hibernate SessionFactory @Column命名不起作用

    问题: Springboot启动报错: Caused by: org.springframework.beans.factory.BeanCreationException: Error creati ...

  3. hibernate多对一双向关联

    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...

  4. Hibernate中事务的隔离级别设置

    Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下

  5. Hibernate中事务声明

    Hibernate中JDBC事务声明,在Hibernate配置文件中加入如下代码,不做声明Hibernate默认就是JDBC事务. 一个JDBC 不能跨越多个数据库. Hibernate中JTA事务声 ...

  6. spring applicationContext.xml和hibernate.cfg.xml设置

    applicationContext.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans ...

  7. [原创]关于Hibernate中的级联操作以及懒加载

    Hibernate: 级联操作 一.简单的介绍 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似 ...

  8. hibernate的基本xml文件配置

    需要导入基本的包hibernate下的bin下的required和同bin下optional里的c3p0包下的所有jar文件,当然要导入mysql的驱动包了.下面需要注意的是hibernate的版本就 ...

  9. Maven搭建SpringMVC+Hibernate项目详解 【转】

    前言 今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多了,Spring-Security的就留在下一篇吧,这 ...

  10. 1.Hibernate简介

    1.框架简介: 定义:基于java语言开发的一套ORM框架: 优点:a.方便开发;           b.大大减少代码量;           c.性能稍高(不能与数据库高手相比,较一般数据库使用者 ...

随机推荐

  1. HTTP错误汇总(404、302、200……)

    HTTP 400 - 请求无效HTTP 401.1 - 未授权:登录失败HTTP 401.2 - 未授权:服务器配置问题导致登录失败HTTP 401.3 - ACL 禁止访问资源HTTP 401.4 ...

  2. django上传图片和文字记录

    直接上代码 html <form class="form-horizontal" id="upload-form"> <div class=& ...

  3. window7快捷键

    新建文件夹:Shift +F10  松手  shift  + w 两遍 Enter   shift+F   Enter

  4. mybatis n+1问题

    mybatis的一对多或者多对多的时候,2中方式解决,一种是嵌套select,但是会有n+1问题,不推荐:另外一种是使用一条sql,在该sql里面使用子查询的方式来完成.比如 select * fro ...

  5. HDU 5876:Sparse Graph(BFS)

    http://acm.hdu.edu.cn/showproblem.php?pid=5876 Sparse Graph Problem Description   In graph theory, t ...

  6. 仿iOS底部弹出popUpWindow

    上面为弹出来的效果 popUpWindow布局: <?xml version="1.0" encoding="utf-8"?> <Linear ...

  7. [转]android使用shape stroke描边只保留底部

    在项目中遇到这种情况:由于一些原因,自己需要用LinearLayout的垂直布局做出ListView的那种效果,但是ListView是自带了分割线的,而且顶部底部都是没有分割线的,每个item中间都是 ...

  8. hihoCoder 数论五·欧拉函数

    题目1 : 数论五·欧拉函数 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho有时候会用密码写信来互相联系,他们用了一个很大的数当做密钥.小Hi和小Ho约定 ...

  9. 用R分析时间序列(time series)数据

    时间序列(time series)是一系列有序的数据.通常是等时间间隔的采样数据.如果不是等间隔,则一般会标注每个数据点的时间刻度. time series data mining 主要包括decom ...

  10. htmlnav

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...