Hibernate之N+1问题
什么是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问题的更多相关文章
- hibernate多对多关联映射
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- 解决 Springboot Unable to build Hibernate SessionFactory @Column命名不起作用
问题: Springboot启动报错: Caused by: org.springframework.beans.factory.BeanCreationException: Error creati ...
- hibernate多对一双向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- Hibernate中事务的隔离级别设置
Hibernate中事务的隔离级别,如下方法分别为1/2/4/8. 在Hibernate配置文件中设置,设置代码如下
- Hibernate中事务声明
Hibernate中JDBC事务声明,在Hibernate配置文件中加入如下代码,不做声明Hibernate默认就是JDBC事务. 一个JDBC 不能跨越多个数据库. Hibernate中JTA事务声 ...
- spring applicationContext.xml和hibernate.cfg.xml设置
applicationContext.xml配置 <?xml version="1.0" encoding="UTF-8"?> <beans ...
- [原创]关于Hibernate中的级联操作以及懒加载
Hibernate: 级联操作 一.简单的介绍 cascade和inverse (Employee – Department) Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似 ...
- hibernate的基本xml文件配置
需要导入基本的包hibernate下的bin下的required和同bin下optional里的c3p0包下的所有jar文件,当然要导入mysql的驱动包了.下面需要注意的是hibernate的版本就 ...
- Maven搭建SpringMVC+Hibernate项目详解 【转】
前言 今天复习一下SpringMVC+Hibernate的搭建,本来想着将Spring-Security权限控制框架也映入其中的,但是发现内容太多了,Spring-Security的就留在下一篇吧,这 ...
- 1.Hibernate简介
1.框架简介: 定义:基于java语言开发的一套ORM框架: 优点:a.方便开发; b.大大减少代码量; c.性能稍高(不能与数据库高手相比,较一般数据库使用者 ...
随机推荐
- Tomcat端口被占用快速解决方案
在dos下,输入 netstat -ano|findstr 8080 //说明:查看占用8080端口的进程 显示占用端口的进程 taskkill /pid 6856 /f //说明,运行 ...
- TI CC2541的整体目标
1. App端会发送一定数量的byte过来蓝牙, 每2个byte是一个汉字的编码. 2. 拿到汉字编码之后, 统计字符数量, 然后通过SPI, 搜索编码 3. 收到的编码, 每个汉字字符有32个byt ...
- Java字符串转换
public class StringConvertToInt{ public static void main(String[] args) { String a ="12a34bW()5 ...
- Mac下使用Automator实现截屏编辑保存
以前在Windows下使用百度或者搜狗输入法的截图工具很方便.❶快捷键(Alt+X,我设置的是这个),❷选择区域,❸编辑所选区域,包括添加文字,线条框框,调色,❹点击『✔️』选择保存位置,修改文件名保 ...
- settings.xml
<settings> <!--本地仓库.该值表示构建系统本地仓库的路径.其默认值为~/.m2/repository,windows:C:/Users/Administrator/.m ...
- Hibernate,JPA注解@Embeddable
JPA嵌入式对象(又名组件) 在实体中可以定义一个嵌入式组件(embedded component), 甚至覆盖该实体中原有的列映射. 组件类必须在类一级定义@Embeddable注解. 在特定的实体 ...
- Codeforces Round #336 Zuma
D. Zuma time limit per test: 2 seconds memory limit per test: 512 megabytes input: standard input ...
- 封装NPOI导出含下拉列表的Excel
/// <summary> /// 绑定数据的方法 /// </summary> /// <param name="ssfworkbook">H ...
- 【20160924】GOCVHelper 图像增强部分(3)
//顶帽去光差,radius为模板半径 Mat moveLightDiff(Mat src,int radius){ Mat dst; Mat srcclone ...
- Unix网络编程--卷一:套接字联网API
UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 0.准备环境 1.简介 2.传输层:TCP.UD ...