spring-boot data jpa

问题:

1、一般情况下,配置好映射@OneToOne @OneToMany @ManyToMany

2、在配置下fetch类型,Lazy或者Eager。

3、然后from one 或者from many时候的就能正常查询。

但是以上查询,

1:在N-1或者1-1的时候,会出现两条查询sql(不管是Lazy还是Eager,只要使用one方)

对于N-1,先查询Many方实体,其次再查询one方的实体;

对于1-1,先查询当前one实体,其次再查询关联方one实体;

这两种方式性能都可以忽略不计,因为不管怎么样Lazy也好,Eager也好,都是两条sql, 其实一条sql也可以解决,下面再说,可以忽略不计

2:在1-N或者N-N的时候,会出现性能问题, 不管是Lazy还是Eager

对于1-N,先查询one方实体,其次再查询many方实体,也是两条sql(只要使用many方),

如果是Lazy,那么只查询one方实体,内存中只加载one方,而不会加载many,只在需要的时候加载,内存占用小;

如果是Eager,那么不仅加载one方,仍然要加载many方,内存占用会大,且立刻执行两条sql;

如果满足条件的one方有100个,那么也就意味着many方也需要查询100次,因为是100个(1-N),这会影响效率,应该是一条sql搞定!

为什么N-1或者1-1不会出现这种问题? 因为右边都是1啊,只查一个啊,左边再多,右边都只有一个

对于N-N,其实就是两个1-N,跟上面效果一样。

解决方法: 加fetch

示例:

@Query(value = "select b from Booking as b " +

"left join fetch b.account as a " +

"left join fetch a.userInfo as u where b.careType=?1 and b.typeId=?2")

List<Booking> findAllByCareTypeAndTypeId(Integer careType, Long typeId);

关系:Booking关联Account(ManyToOne),Account关联UserInfo(OneToOne)

结果:这个查询的结果是,不管满足条件的Booking有多个还是一个,但是同时立刻抓取出与之相关的account实体值以及account实体关联的userInfo值

适用于任意关系(1-N/N-1/1-1/N-N)

注意点:

1、第一个left join fetch后面必须跟b.account而不是Account实体!

2、第二个left join fetch后面必须跟a.userInfo而不是UserInfo实体也不是b.account.userInfo这种方式!

3、通过这种方式会无视fecth类型,避免出现多条sql,避免N-1问题

4、这种方式同样适用与N-1或者1-1,因为默认查询会出现两条sql,这种方式自始至终只会是一条sql!

完!

原文 

http://www.blogjava.net/liuguly/archive/2017/11/13/432890.html

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » spring-boot data jpa

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址