Hibernate N+1 问题及解决办法

6 篇文章 0 订阅

问题出现的原因:

Hibernate 中常会用到 set , bag 等集合表示 1 对多的关系,在获取实体的时候就能根据关系将关联的对象或者对象集取出,还可以设定 cacade 进行关联更新和删除。这不得不说 hibernate 的 orm 做得很好,很贴近 oo 的使用习惯了。

但是对数据库访问还是必须考虑性能问题的,在设定了 1 对多这种关系之后, 查询就会出现传说中的 n+1 问题。

一对多: 在一方,查找得到了 n 个对象,那么又需要将 n 个对象关联的集合取出,于是本来的一条 sql 查询变成了 n+1 条;

多对一: 在多方,查询得到了 m 个对象,那么也会将 m 个对象对应的 1 方的对象取出, 也变成了 m+1 ;

解决问题的方法:

      1、 使用 fetch 抓取, Hibernate 抓取策略分为单端代理和集合代理的抓取策略。

Hibernate 抓取策略 ( 单端代理的抓取策略 ) :

   保持默认也就是如下 :

    

    fetch="select" 就是另外发送一条 select 语句抓取当前对象关联实体或者集合设置 fetch="join"

     

Hibernate 会通过 select 语句使用外连接来加载器关联实体活集合此时 lazy 会失效

       Hibernate 抓取策略 ( 集合代理的抓取策略 ) :

            保持默认( fetch="select" )也就是如下 :

        

                 

                 

             

             1)fetch="select" 会另外发出一条语句查询集合

             2) 设置 fetch="join" 采用外连接集合的 lazy 失效

             3) 这只 fetch="subselect" 另外发出一条 select 语句抓取前面查询到的所有的实体对象的关联集合 fetch只对 HQL 查询产生影响其他的则不会

       2、 使用 map 直接搜索需要的列

如:产品 product 和产品分类 product_category 两张表,多对一关系。查询产品列表时

select new Map(p.id as id, p.name as name, p.category.name as categoryName) from Product p

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值