关于hibernate的n+1问题以及解决办法
hibernate的n+1问题已经是一个很常见的问题了。
最近遇到了很多次的n+1问题,总结一下解决办法:
1.ManyToOne中的n+1:
当查询单个的时候,可以使用aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaIAAABWCAIAAAACHQWDAAAQRElEQVR4nO2dv08juxbHff+AV9//YWuEtPN3XEoKpMh/wTZIK4io6NYgQTPadiUEWqqZ7inZYiWUgkhPyzZTXBo2iO3Q0uJXeGwf28eTyWQCmeF8dSSC419hmE/OsT02kw1UXJ6wrRNx16Rsl1SIhBklonjt/pBIpCZir90BEolEWq0IcyQSqecizJFIpJ6LMEcikXouwhyJROq5CHMkEqnnIsyRSKSeizBHIpF6LsIciUTquQhzJBKp5yLMkUiknoswRyKRei7CHIlE6rkIcyQSqecizJFIpJ6LMEcikXouwhyJROq5CHMkEqnnao65WTYcDAaDwWCYzVrs0Ksr54znMMFuld7GPulB9WuqrvRzaRUiof3v+66GmJtlQ423WTYcpFMpp6kl3iwbDgbpdNnOGZIaVSEV5G7cdCES/+7OeT28IUUxrQQfOWdA1fU376dzNMbKz8d44GzMrN3ozjyJZMzYmPGHWGaeR4rnNyBlYvqe83l/M1LH1Qxz0xSSZJYN0+ksGw6HQ4WhWZam6bA9L89tLppHZwIMXkwYAWpS4dUxV7vS5fv5Io5ecZuUwPIav2HshvMxS24Lm+JRDy9eiInG5QN3itT9KiN1VE0wN8uGw2wmp6l2nabpMPtfNhxm0yzNZnKWZdMyjzS5oJM1TQdp5sa8Lpo8UAWYCxw37VLaAsNshjaEFlfy/tkD50XfNeANlRTkTBxPwcmbc8ZzndrWvYWDZ1X9dForRALeNr/lnHGhm3Pfr+VzyvwGOlxaTyIZJ+Ip5+MIsKqK5xaOfqnaX2akTqoJ5qbpMJspkiialZhLp3KWpVmWplNpMGdlUTRNDWCsE6bRJANohc6jk7NELmwOBtJYQ6Y2WA7/Sg9uAHiTwyJ4vBvcPDmHJKm4t6KUReQErWWPVtdPD6qgcls3KG5BGOsS+uknzI9DLbysX5bflO8Wt4nKnNwWePEnkZRoK8TEhyBxrtdqgDkToyq8pFM5TYfZfxU8NGAs5qA7F4IGEM0gJ0Ckg7nQcUunFZgLGvIH/CDmIi4RTPbpU4EP9E4GrbR3a9UYSGuxn35rpjwYzYd5dPlol0I9iQSEpTDR5RRw6yTw0bDihoPOSF/1H4HUEzXAnHbmrM8GMAdyadCEPhqOOemgU4Z1hSXMexVBq9+QR0SrepiL3g5tY25Bbw7xxlbVT2wuOhGF76wFmFuAJFgo6kwgjBHM2fG4aHGeY65c9I9A6omWw5xCxjQdpFMfThY/0KurxJyqOgvnG+YHrXgi3hCYrHBUP2jFiROUL0SCBoMv4s2tsJ8oVBMhYDLIYzsSj9JBjCtlCaxEPIEc1pWTEsSq5oUE43FIcRDnYu9S0NpvNQ1aFbWGaTpUcZ8/nGYIY2JWALAo5iALkbrcbP4KEyQx7jZiS1RQziH//9DPwucsnAgRGdqPVt1Qc6cgWu1nDKowFY4WgrYjXVLJAJKu48YffBcMoModhgsXjpRwBPMPSEhLlOu3mk1BtLAmLlr1K642pn/2xvK/Irq1upgi1p6r0bo5CKNp2h7yYuHky4lA10hhNNolzNHy4N5riacgln3iwJGKONfhubEu3aBrIBWdBr5Qd/6K3ekpqbHo0X0SidRzEeZIJFLPRZgjkUg91+ttxNTSLiZGZj3JKiYx1nwA518h3zE5knKXyX+E89bnRL5j8l2Qvuaq+ETtyqx88ZbMzF2SrTNi2wvULd6OfvKtfba1z7b2+SSS5e5bUuY5EXdN2uj4dlXtbcTkPtY1n321MQeqnVtrsHyvDXVg+jUvofA5caGQy3eJ/PeVOrWUYp9oJUKvcJ3LXvH190L/Nb/Fh3324VsdAhWXJ40x1/H56NY2YvLebmnOdFGXbwWY6wDkLM4+J3IX9PVfId/xV+vUUop8otWow5j7ybf22dHPOlmXw1ynVxe2thGT96h99a5HWICJbZoUo1Z0PQv6wKvzziwbDrMs1Y9l6BoiWzYh1xbfYgiu+jcbcyRCcMZY+UP/09ffjGgJqaAP2khKKeWIy10h/3ETZWFTFFP+FfIfIXeZfJfIz9ymo9p16wnrtO5Y0FC0S0sJvUYVz3XUwlx4iSu3qwrqXM11DzBn41M/RA0xlx+ZnDbgLS5P0OId+cZH1dpGTDjm8EdNpfkdf85LLxPG98dcrE4Ec4PycVz7ASJbNknsG2zeTkrOfhw8lzlnLBGFHtyovRnRIo/uxxR6cyNuw9gRl7t5iZ7P5U5K5WtvaExRLyYUc2XlsZxS7upGkS4tK/QaLYs57B10vym0ePvX/bf4YCHFtsLQ1Y9nfcxNzpHhvMm5yZMf7bOtc5/UneRcaxsxoZiLU6fyTYikAHMt1Am2TgGYQx+zDaOSyN3ibPmmMQf25Sgxt8BmRC0IxZzHES+PymASdzX1FsVc6U7C1oErp8xgru2wFL1GS2MuuMT4Rizoryu77mHQ6uKvAnPW77Msg/4d4tB1NW5tbSOmVWAOffprLTGHbC2JY67+/8nKvLmXwVypHMAuMh/SEczFdg+th7mVXXcfc/mRYdM8b05pcl4S7einxDw4R28Tc2AjJilnWWb2x8SOZVg8wMSnIBar0/J20BBzYdAa3C0gYDFhDI65l52wqoO5aNC6COZUcbV4ZeS9Ddi3i43xLYY5fyuUWKaKryJ/P5RamMMucWS/KbTOVV13FHPnudTO2lzMmUo+fCv0wFxsYcqbC1r9jZiklHZmwfHtkP2R/A18zSQABhpsmUrdOuHivixtgjl8CiJ0CkxAY/Zdi2Auvj/SClQLc1L7XCCQXAhzZrpDzVqMpJRgvZ4zfQHj1mbjcSGjEOHXyPzhwd54vu9kvrVCfyq8xJH9pvDiK7ruFVMQ5+LyBMIL2HkugR/nxq1OZme8r7OUW7eNmNZQ3b22/VSn1291Wl2NWOWabcS0piLQrYmUP9TVW63j6vTXy7psxLTmWvOHvV5Gu+48KQxyST1Xx28Adv/43C0bY3r1XnXX/v7PX3//569X7wYZ2eqsk5ibm0JW3whzZL03wtxbN8IcWe+tOeZ+fC2H5z5+/bWy/l0fD9KRmwih9mWHbV+sDnPZNuNfWqlq+mmjraqW78nmpyuQQpgj6701xNyPr8PBXvbj8fn+8dfZ3uD4+/P94/Po1Fm4NqqqwZaqtCrMXR2+ZzuZSfmy46xVqmRKcbDJti/mto5h7oIz9v5g+nz/qOBVp57GmHvYhgfx7TzoD26O7JvontxuuEc1H0x1trLUwzYbbxz+Kf9QO5lphTBH1ntrhjmXPkX28fT6/vF5dFqHXMqWxhwAh8FcLeI8Pi+DuavD9xub7zcOi/vH56tDvr1Tvp5jS3pz09sNC6kxYzdfHp/vH/8cbI7Z5u2V7dtEv/Wsc+rM09sNNtYfOds2pCbMkb0Ba4K5H1+HH7/+uv9ePopw/P36eC/7EcNckX3UDp5610S75kmGs6LMDPxBRbfr40E60g2p6NhAzfClCnPTTxvawVPvXh2+dx8ZtDc88AcVkrJtxr9clAvdNdrebxxmBzufrh6Lg8Ps6lBjLmjIS7QOJpqz2i5uSscN8O4e5Zql3p+DzfHG5qQsaGp41H8E7dAR5sh6b00wNzodnhXXx4PhWfHrbG94VljMWZUhLXTHVBH1GvHmRqeDwem129b18UAnfk8V+8bjseePIEFrOfwE3TFYBPHmvFBOF9GJF1xx6urw/fbF89UhPzjk2xfPJeamnzacSFa9zrYNyKw3F+tSlRmcYf6a+fXPwaYNbFWUun1RxqpXhxPo90HvkjBH1ntrgLlfZ3vpqMg+7mU/SorFvTngyrmOW4g5CEGYqClZZB8dzNkYMOrNOc4UdNxCzKHEAa1oLpSt6F8V5qBzZHtywZkZ7DdYiXapwmxwGvpr9lfX0dPum2LfrUtA5/MS5sh6bw0wd328l/34ng5Or+8N7GKY+55qt86zF8EcBI1jS2MONrGTLYC5aJcq7GG7nEmYyzUz+uY5gGMGc7qflzBH1ntbDnOKYuo1PjZ3fTzApxpGp95KlF9ne2jQGsMcErQGQ10gbHQNDu3dPz4r8GFBay3M4UGrTSwONuF4X2RI7oI7o3UXNwpMV4cTM6w2b/5hAsYZtft2caMw5zRKQSvZW7KmQasaNdtLj/dsKDp3CsLx7Gy6E8kiUxA2v8FckykIx42y6U4ki0xB2Pz8S+gGKsw9lpDy4lAz3bF94VWFdEllNpV/OZyYNSKgxT8Hm2WiYRxYXzJmwO/T7ptalWJH9O5pCoLsjVmzKYj6C0fat9iCErLaRgtKyN6WNVo3B0fcvqcvjLzY8mCymkbLg8nemi3xFEStpx3aN9qhZCkzUbY2whxZ763hfnMkEonUFRHmSCRSz0WYI5FIPdeLYA6cHUlqonmnUZgDpuptZP0kknL1SSKe2uojibS2Wn/M3X1L4gdH1mqds1c7JwU9uR2ealwPTLUO3al9Mk9+w5Lb1v4cTm1PIhl3+cwAUj+1/kHrspjLeSJyc0jqCws53j1JEn0qMue8Xr9axVwhJow/zM9XU4Q50tqrEeaKyxO2dc6PyjNrSwbdfUu2TsTdb/Fhn5kjcu3huNqbUynmAN27b8nWfnL5G+Q0mX9y5wxdezguODF3npOYc/cwaJ1qH3jIKxLBEcLgdHX0RHcu7GnHhQwPJbaHUueCi0IWQuToGdXuSe91uuT3JnrdhPu8BLvRZ2mPubhN3ERZmJSxPrp5kohbzsYsuRVcp8cwB4rb0DioM9q6vh4ETdLyao65ElX5kT6y++5bsnXCj87FncpgAeT9aotoYrr/yr/FB3Dcd+jNTc5NbbAqVIpy0uEceuIkkliIxAkw1esY5uDh7KYixJvjuSwEF4LzXPcq2hA8sN3y1PLBicWbe3M5HxtU5XzMc8Wjie5S+boQE8ZucvnA2TgRT4WYJOIphrmyHkcP3FLsgev6kdbN5yPMkdpQc8xpbBnoeG5aLL+E5PotPuwnl7+lLF+HjluIufzIdfEqHDpw51vOoYeHI4keNjRgot5ckBjWofPpZNUpvCHYI5PDdxFbw1xAeCePyqATS0JVY670HGFDwJVTO7kbzBHLSCvV0pizr+ODaD7mFNGOfuo4V0pnmmKONzfXg7PtolBYA8y5vy+AObTvkbZiehnM6ZI3FnaRqQ/CHGnVWhZzAEkLYE75gOfi8sR4f27w62NOe3ymtjqTEt59r/05dIITS4zGknDwrRpzPpdQzOEN2USvoRjL2sRcNGgNMefnvPG7YBMfOEOIFsXca06Rk3qlZcbmStOOFYq5ybkbYBovrJxesPntFMS5uDyxmINRKjIFsQ9zur3EFnPoiMq6eY7nhcw3BOGhyZcIwedhDtQahqegXGVDPPfq9/L6Xuv8iYi5mJPaEQPRJY45Z2ZD8w4szYOzDU7cio7HuR1N5n4YEqmGlh+bI5FWJOjlkkjNRZgjraOUJ0eMI7UiwhyJROq51v8pCBKJRFpKhDkSidRzEeZIJFLPRZgjkUg9F2GORCL1XIQ5EonUcxHmSCRSz0WYI5FIPRdhjkQi9VyEORKJ1HP9H1JX8RFFMfx/AAAAAElFTkSuQmCC" 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的关联,后台在查询数据时已经作了健全性判断,但还是经常抛出对象找不到 ...
随机推荐
- RabbitMQ消息机制广播分发
public static void SendMessage() { var factory = new ConnectionFactory(); factory.HostName = "1 ...
- 自己用C语言写dsPIC / PIC24 serial bootloader
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). HyperBootlo ...
- angular表单
angular的表单,点击确定进行创建,支持批量创建,表单验证有样式提醒; <!DOCTYPE html> <html lang="en"> <hea ...
- C语言中两种方式表示时间日期值time_t和struct tm类型的相互转换
使用gmtime函数或localtime函数将time_t类型的时间日期转换为structtm类型: 使用time函数返回的是一个long值,该值对用户的意义不大,一般不能根据其值确定具体的年.月.日 ...
- 【英语魔法俱乐部——读书笔记】 0 序&前沿
[英语魔法俱乐部——读书笔记] 0 序&前沿 0.1 以编者自身的经历引入“不求甚解,以看完为目的”阅读方式,即所谓“泛读”.找到适合自己的文章开始“由浅入深”的阅读,在阅读过程中就会见到 ...
- HTML5 CANVAS画图 beginPath和closePath
beginPath这个canvas函数我很早就讲过了,他的作用很简单,就是开始一段新路径,我们先来看下面的一小段代码: var ctx = document.getElementById('cvs') ...
- windows 下 node.js 和 express 的安装
下载 node 下载和安装 下载地址 https://nodejs.org/en/ 下载文件 node-v4.5.0-x64.msi nodejs 安装 express -g 代表全局安装 npm i ...
- jahshaka 2.0 环境配置
经过断断续续的探索,终于在自己的win7电脑上编译并运行成功了jahshaka源代码. 环境配置: 首先,jahshaka 2.0提供了vs 2003 和vs 2005两个版本的工程文件,还需要qt3 ...
- UGUI&&Animator模块知识点随记
1.Render Texture,把这个赋给摄像机,这个对象就保存了摄像机拍摄到的纹理,再把他赋给Raw Image. 2.给Button添加事件关联时,函数不能带有yield WaitForSeco ...
- 深入理解js——作用域和上下文环境
如图除全局作用域外,每个函数都会创建自己的作用域.作用域在函数定义时就确定了,而不是在函数调用时确定. 下面按照程序执行的步骤加上上下文环境. 第一步:程序加载时已经确定全局上下文环境,并随着程序的执 ...