什么是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. JQuery ajax方法及参数

    ©屋主原创,版权归 todayeeee 所有!如需转载,必须在页面明显位置给出原文链接!商业用途请 联系我!   $.ajax({ type: 'GET',    // 这是请求的方式 可以是GET方 ...

  2. Gson将参数放入实体类中进行包装之后再传递

    package com.sinoservices.dms.orderinfo.entity; public class OrderDetailKeyCondition { //工单主键 private ...

  3. 浅析String、StringBuffer、StringBuilder的区别以及性能区别

    前奏: 比较三者之间的区别在与区别他们做相同的事情的时候的区别,那就是在我们常见的拼接字符串的时候,StringBuffer.StringBuilder调用的是appende()方法,而String很 ...

  4. inupt textarea提示文字(点击消失,不输入恢复)及限制字数

    效果: input: textarea: 限100字 源码: input: <input name="textfield" type="text" max ...

  5. 关于hibernate对应关系之后取值的问题

    hibernate对应关系之后取值,比如一对一关系,取不到值,需要检查PO类中是否生成了getter及setter方法.

  6. 温故而知新 clone

    浅复制(浅克隆) 被复制对象所有变量都含有与原来对象的相同值,对象中对其他对象的引用仍然指向原来的对象,换言之,复制对象只复制考虑的对象,而不复制所引用的对象.继承自java.lang.Object类 ...

  7. [转]application windows are expected to have a root view controller错误

    转载地址:http://blog.sina.com.cn/s/blog_6784e6ea01017jfy.html 最新更正:这个提示几乎不影响编译和运行,可以不用设置.     产生这个提示的操作: ...

  8. Mysql-学习笔记(==》建表修改一)

    -- 建立表CREATE TABLE 表名( )ENGINE=存储引擎(MYISAM INNODB) AUTO_INCREMENT=100 DEFAULT CHARSET=utf8; CREATE T ...

  9. C# 中var as is 泛型集合

    一.var var:万能变量类型,跟JS一样. 二.as:非强转类型. 强转类型:一般在变量前面加:(所需类型).如果转换失败,系统就会报错,如果用as,就不会报错,转换失败的话,就会返回null, ...

  10. font awesome 符号字体

    http://www.fontawesome.com.cn/ 引用CSS包之后根据图标库找到所需的图标代码 使用i标签或者a标签皆可,符号为文字性质,可以直接通过修改text颜色从而修改符号颜色