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.抓取内连接    

  抓取内连接与内连接不同之处在于其对象的内存状态不一样。HQL中使用inner join fetch进行抓取内连接。  
 

关于hibernate的n+1问题以及解决办法的更多相关文章

  1. Hibernate不能自动建数据表解决办法

    首先自己要注意自己的MYSQL版本,然后设置对应的方言 兼容性模式 <property name="hibernate.dialect">org.hibernate.d ...

  2. Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister报错解决办法

    在做Hibernate框架数据库的关联关系映射练习中出现了Could not get constructor for org.hibernate.persister.entity.SingleTabl ...

  3. Spring定时器调用Hibernate方法无法获得SessionFactory的解决办法

    由于在Spring定时器中无法通过注解的方式获取bean,因此需要通过原生的方式获取.获取session的方式如下: WebApplicationContext wac = ContextLoader ...

  4. 在IntelliJ IDEA中添加框架支持时找不到Hibernate的解决办法

    问题描述 第一次在Add Frameworks support界面中添加hibernate支持的时候,异常中断,导致没有成功添加. 第二次进入Add Frameworks support窗口时,发现找 ...

  5. Hibernate报错:org.hibernate.ObjectNotFoundException: No row with the given identifier exists 解决办法

    报错信息: org.hibernate.event.internal.DefaultLoadEventListener onLoad INFO: HHH000327: Error performing ...

  6. paip.hibernate list 返回位null的解决

    paip.hibernate list 返回位null的解决 但是size是对的... 里面都是null... hb3.2版本...oracle11g =========原因:没主键 也许没主键,看累 ...

  7. 数据表列名与数据库关键字冲突,在Hibernate下的解决办法

    设计了一个数据库,某一个列名字是key,这与mysql数据库关键字冲突了,Hibernate下save总是报错. 在mysql命令中,解决办法很简单,只需要将关键字key用引号括起来就好了. 在Hib ...

  8. Hibernate常见问题 No row with the given identifier exists问题的解决办法及解决

    (1)在学习Hibernate的时候遇到了这个问题"No row with the given identifier exists"在网上一搜看到非常多人也遇到过这个问题! 问题的 ...

  9. org.hibernate.ObjectNotFoundException: No row with the given identifier exists解决办法

    hibernate-取消关联外键引用数据丢失抛异常的设置@NotFound hibernate项目里面配了很多many-to-one的关联,后台在查询数据时已经作了健全性判断,但还是经常抛出对象找不到 ...

随机推荐

  1. 洛谷P2409 Y的积木

    P2409 Y的积木 77通过 491提交 题目提供者zhouyonglong 标签云端评测 难度普及+/提高 提交  讨论  题解 最新讨论 这组数据几乎可以卡掉所有程- 第一个题解有点问题 求教大 ...

  2. 二叉树遍历(Binary Tree Traversal)

    二叉树的递归遍历比较简单,这里说一下非递归遍历,以中序遍历为例子. 非递归遍历主要用到栈来协助进行.对于一个二叉树,首先根节点入栈,如果有左儿子,则继续入栈,重复直到最左边的儿子,这时候此节点值为要遍 ...

  3. web.xml常用元素配置

    tomcat服务器: tomcat是一个WEB服务器,所有的j2ee WEB程序可以在此处运行. tomcat服务器是一个符合j2ee标准的WEB服务器.则J2ee的EJB程序无法在此处运行. 如果要 ...

  4. mongodb ubuntu下自启动

    个人测试开发的时经常会采用shell 启动mongodb,当进入项目团队开发测试时,必须让mongodb可以随系统自启动. 1.编写启动命令 sudo vim /etc/rc/local 1-1 mo ...

  5. highCharts 饼图动态加载

    饼图的动态加载 (1):导入样式 <script type="text/javascript" src="<%=request.getContextPath( ...

  6. {POJ}{3988}{Software Industry Revolution}{DP好题}

    题意:给定一个字符串d,要求用另一字符串s去匹配,其中s中的?可以为任何字符,*可以为任意个字符,求最小的匹配权值 思路:这题和CSDN英雄会的“反相互”类似,由于其中某些字符的不确定性,利用动态规划 ...

  7. VC++ 在使用 CImage 的Draw 输入一个图像时,有时候会造成图像失真严重,解决的方法如下

    VC++  在使用 CImage 的Draw 输入一个图像时,有时候会造成图像失真严重,解决的方法如下 失真主要是由于变形造成的.只要设置一下变形的模式就可以了 ::SetStretchBltMode ...

  8. 将复杂查询写到SQL配置文件--SOD框架的SQL-MAP技术简介

    引言 今天看到一片热门的博客, .NET高级工程师面试题之SQL篇 ,要求找出每一个系的最高分,并且按系编号,学生编号升序排列.这个查询比较复杂,也比较典型,自从用了ORM后,很久没有写过SQL语句了 ...

  9. 驱动学习---PAE--virtual address to physics address

    PAE是Physical Address Extension的缩写,即物理地址扩展.简单来说,就是把IA-32处理器的寻址能力从原来的4GB扩展到64GB.寻址4GB空间,要求物理地址的宽度为32位. ...

  10. Button模板,样式

    一.button控件上的模板 <Button Content="Button" Height="25" HorizontalAlignment=" ...