关于hibernate的n+1问题以及解决办法
hibernate的n+1问题已经是一个很常见的问题了。
最近遇到了很多次的n+1问题,总结一下解决办法:
1.ManyToOne中的n+1:
当查询单个的时候,可以使用aaarticlea/png;base64,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" alt="" />来进行让其join查询,
觉得manyToOne的n+1问题同样可以使用这种方法,其中FetchMode有三个参数:
public enum FetchMode {
/**
* use a select for each individual entity, collection, or join load.
* 产生n+1的查询,每个都生成一条查询语句
* n+1条查询
*/
SELECT,
/**
* use an outer join to load the related entities, collections or joins.
* 使用一条outer join进行查询
* 1条查询
*/
JOIN,
/**
* use a subselect query to load the additional collections.
* 使用一条查询list语句进行查询
* 2条查询
*/
SUBSELECT
}
2.查询主体为list的时候的查询
上面的办法应该是可以解决n+1,但是在查询主表的列表是竟然发现还是会产生多一条语句的情况,于是经过百般查找,找到了一种通过hql来解决此问题的方法:
@Entity
@Table(name = "xxxx")
public class ShowInfoEntity implements Serializable {
private static final long serialVersionUID = -5078958740245381213L; // id
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id; // numapi
@OneToOne(fetch = FetchType.EAGER, optional = false, mappedBy = "showInfo")
@Fetch(FetchMode.JOIN)
private ShowNumber numapi;
首先这个是主表,其中与从表ShowNumber有一个关联关系,此关联关系是定义在从表中的。
看到这个类上有配置@Fetch 其在查询单个ShowInfoEntity时是能完美的起作用的,即是join查询,但是在查询List<ShowInfoEntity>时就没有这么幸运了,
会先查询一个List<ShowInfoEntity> 之后在查询n条numapi,
使用left join语句也不能解决问题,
最后找到了left join fetch:
@Query("select t from ShowInfoEntity t LEFT join fetch t.numapi r where t.enable =0 and t.accountId in (?1) and t.timeline<?2")
List<ShowInfoEntity> findByFlush(List<Long> toUsersPredicate, Long time, Pageable page);
顺便说一句,hibernate 的hql语句中的join挺麻烦的,需要先配置好关联关系,然后join 主表.从表
列举一下hql中的join连接
1。左外连接
左外连接(Left Outer Join)查询出左表对应的复合条件的所有记录
2.左外抓取连接
左外抓取连接指定在Hibernate检索数据时,采用抓取的方式,直接将数据加载到与主表对象关联的从表属性中。
3.右外连接
HQL中使用关键字right outer join右外连接
4.内连接
内连接(Inner Join)是指两个表中指定的关键字相等的值才会出现在结果集中的一种查询方式。HQL中使用关键字inner join进行内连接,
5.抓取内连接
关于hibernate的n+1问题以及解决办法的更多相关文章
- Hibernate不能自动建数据表解决办法
首先自己要注意自己的MYSQL版本,然后设置对应的方言 兼容性模式 <property name="hibernate.dialect">org.hibernate.d ...
- Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister报错解决办法
在做Hibernate框架数据库的关联关系映射练习中出现了Could not get constructor for org.hibernate.persister.entity.SingleTabl ...
- Spring定时器调用Hibernate方法无法获得SessionFactory的解决办法
由于在Spring定时器中无法通过注解的方式获取bean,因此需要通过原生的方式获取.获取session的方式如下: WebApplicationContext wac = ContextLoader ...
- 在IntelliJ IDEA中添加框架支持时找不到Hibernate的解决办法
问题描述 第一次在Add Frameworks support界面中添加hibernate支持的时候,异常中断,导致没有成功添加. 第二次进入Add Frameworks support窗口时,发现找 ...
- Hibernate报错:org.hibernate.ObjectNotFoundException: No row with the given identifier exists 解决办法
报错信息: org.hibernate.event.internal.DefaultLoadEventListener onLoad INFO: HHH000327: Error performing ...
- paip.hibernate list 返回位null的解决
paip.hibernate list 返回位null的解决 但是size是对的... 里面都是null... hb3.2版本...oracle11g =========原因:没主键 也许没主键,看累 ...
- 数据表列名与数据库关键字冲突,在Hibernate下的解决办法
设计了一个数据库,某一个列名字是key,这与mysql数据库关键字冲突了,Hibernate下save总是报错. 在mysql命令中,解决办法很简单,只需要将关键字key用引号括起来就好了. 在Hib ...
- Hibernate常见问题 No row with the given identifier exists问题的解决办法及解决
(1)在学习Hibernate的时候遇到了这个问题"No row with the given identifier exists"在网上一搜看到非常多人也遇到过这个问题! 问题的 ...
- org.hibernate.ObjectNotFoundException: No row with the given identifier exists解决办法
hibernate-取消关联外键引用数据丢失抛异常的设置@NotFound hibernate项目里面配了很多many-to-one的关联,后台在查询数据时已经作了健全性判断,但还是经常抛出对象找不到 ...
随机推荐
- UpdatePanel无法导出下载文件
转自 http://www.cnblogs.com/vipsoft/p/3298299.html protected void Page_Load(object sender, EventArgs e ...
- Scorpio-CSharp简介
Scorpio-CSharp是为了解决Unity游戏各个平台热更新的问题,纯c#实现 基于.net2.0 兼容所有c#平台 语法类似 javascript, 设计初衷是为了做一个所有人都能修改的热更新 ...
- window.onload和window.document.readystate的探究
在编写前端页面的时候,我们时常需要对页面加载的状态进行判断,以便进行相应的操作. 比如在移动端,时常需要在页面完全加载完成之前,先显示一个loading的图标,等待页面完成加载完成后,才显示出真正要展 ...
- 使用spring通知时,代理出错
动态代理是基于接口的,spring配置是基于类的!!!!!!!!!! 注意:JDK的动态代理,只能对实现接口的类实现代理,生成代理对象,如果这个类没有实现接口,是生成不了代理对象的.如本例UserMa ...
- iOS平台使用陀螺仪传感器
在移动端开发过程中,有时候会用到陀螺仪传感器获取当前手机的姿态,下面给出iOS端如何获取陀螺仪姿态数据的代码: //根据陀螺仪的四元数转换为矩阵 + (GLKMatrix4)calculateMatr ...
- 17.linux下root用户与普通用户
默认安装完成之后并不知道root用户的密码,那么如何应用root权限呢? (1)sudo 命令 这样输入当前管理员用户密码就可以得到超级用户的权限.但默认的情况下5分钟root权限就失效了. (2 ...
- 内容生成器:content、计数器、多列
一,内容生成器:content 补充before和after伪类选择器: 1):将内容添加到某个选择器定义的单个或者多个元素的每一个实例之前或者之后 2)与before选择器配合使用(同理大家想下会不 ...
- javascript Windouw 转自 http://www.cnblogs.com/kissdodog/archive/2013/01/01/2841464.html
javascript之window对象 window :window对象是BOM中所有对象的核心,除了是BOM中所有对象的父对象外,还包含一些窗口控制函数. 1.全局的window对象 JavaScr ...
- 免费而优秀的图表JS插件
1.百度的Echart ECharts,缩写来自Enterprise Charts,是百度推出的一款开源的,商业级数据图表,它最初是为了满足百度公司商业体系里各种业务系统(如凤巢.广告管家等等)的报表 ...
- zt:Linux查看程序端口占用情况
http://www.cnblogs.com/benio/archive/2010/09/15/1826728.html yxr注: 由于安装eda工具libero,license要配端口,为确认端口 ...