什么是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. 【python cookbook】【数据结构与算法】1将序列分解为单独的变量

    如果对象是可迭代的(任何序列),则可以进行分解操作,包括元组.列表.字符串.文件.迭代器以及生成器,可通过简单的一个赋值操作分解为单独的变量. 唯一要求:变量的总数和序列相吻合,否则将出错: Pyth ...

  2. javaWeb 使用jsp开发 if 标签

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  3. Spring注解@Scheduled定时任务

    一.首先配置applicationContext-task.xml (1)添加 xmlns:task="http://www.springframework.org/schema/task& ...

  4. OpenCV学习 物体检测 人脸识别 填充颜色

    介绍 OpenCV是开源计算机视觉和机器学习库.包含成千上万优化过的算法.项目地址:http://opencv.org/about.html.官方文档:http://docs.opencv.org/m ...

  5. 7、XML加强/Web开发/Tomcat

    1 XML加强 XML加强 1)Dom4j修改XML文档 写出xml文档: XMLWriter writer = new XMLWriter() writer.wrtite(doc); 增加: Doc ...

  6. DOM元素尺寸和位置

    一.获取元素 CSS大小 1.通过style 内联获取元素的大小 var box = document.getElementById('box'); //获取元素 box.style.width; / ...

  7. hack是什么

    不同浏览器对css的解析是不同是,因此需要css hack来解决浏览器局部的兼容性问题.针对不同浏览器写不同的CSS代码的过程叫CSS  Hack. 常见的hack有三种形式,分别是CSS属性hack ...

  8. hibernate 对应关系级联的意思

    hibernate的关联关系,重点在理解级联cascade和inverse 1.cascade一般用在级联保存,级联更新,级联删除上 1.1cascade注解有两种,一种是基于hibernate注解 ...

  9. JAVA类访问URL

    URI uri = new URI("https://www.baidu.com/");        Desktop desktop = null;        if (Des ...

  10. 线程和进程详解(以java为例具体说明)

    详细参见http://ifeve.com/java-concurrency-thread-directory/ 一.线程概述 线程是程序运行的基本执行单元.当操作系统(不包括单线程的操作系统,如微软早 ...