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. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  2. jq 版的tab切换

    ta切换是在前端中非常常见的一种效果,网上的效果很多.但是我觉得下面这种方法最好,把tab效果封装成一个函数 tabs,这个函数要配合jq使用. var tabs = function (tab, c ...

  3. python脚本基础总结

    1. 注释 ①单行注释:#单行注释 ②多行注释: ''' 三个单引号,多行注释符 ''' ③中文注释:#coding=utf-8 或者 #coding=gbk 2.输入输出 ① 输入:  3.0后的p ...

  4. [转]DevExpress.XtraGrid.GridControl gridView自动列宽代码

    gridView1.OptionsView.ColumnAutoWidth = false;   for (int I = 0; I < gridView1.Columns.Count; I++ ...

  5. 针对APP的测试过程和重点关注内容,做以下梳理和总结

    转载自金阳光测试:http://blog.sina.com.cn/s/blog_12df1b9e60102vy57.html   1. 首先是测试资源确认及准备 (1)产品需求文档.产品原型图.接口说 ...

  6. MYSQL数据库无法使用IP地址访问的解决办法

    1.在运行中输入CMD,确定,进入文本方式. 2.输入mysql -h localhost -u root -p 回车,使用ROOT用户登录. 3.输入use mysql; 显示Database ch ...

  7. JS判断input按了回车键

    参考代码如下: <input type="textbox" id="textbox1" onkeypress="CheckInfo" ...

  8. nodejs 在linux上后台运行

    1.用forever  进行管理 npm install -g forever forever start index.js   2. 用自带的服务nohub     nohup node index ...

  9. springMVC: java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config

    springMVC开发web的时候,报错:java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config 原因:未引入jstl ...

  10. @UniqueConstraint

    jedis UniqueConstraint定义在Table或SecondaryTable元数据里,用来指定建表时需要建唯一约束的列. 元数据属性说明: columnNames:定义一个字符串数组,指 ...