java-JPA中的显式和隐式JOIN有什么区别? (性能)

这些天,我在阅读有关JPA的信息.我了解到可以在JPQL中使用显式或隐式JOIN.

明确加入

em.createQuery(“SELECT b.title, p.name FROM Book b JOIN b.publisher
p”).getResultList();

隐式联接

em.createQuery(“SELECT b.title, b.publisher.name FROM Book
b”).getResultList();

这些示例的来源:link

我的问题是:显式和隐式JOIN在性能方面是否有区别?

更新

我已经读过您写的@MatteoBaldi和@Kayaman,我已经做了一些测试,我想与您分享结果.

我创建了两个实体:学生和课程,并且我创建了manyToOne(许多学生参加一门课程).我使用了JPA的EcpliseLink实现.

查询=从课程中选择学生和dummyFiled,执行方案:

> manyToOne(defaultFetch-> eager),隐式JOIN.结果:完成所有工作的单个SQL查询.
> manyToOne(Fetch-> lazy),隐式JOIN.结果:与1相同的SQL查询.
> manyToOne(defaultFetch-> eager),显式JOIN.结果:与1相同的SQL查询.
> manyToOne(抓取->惰性),显式加入.结果:与1相同的SQL查询.

因此,在测试环境(EclipseLink,..)中,我有从JPQL查询生成的相同的SQL查询.因此,我可以说性能是相同的(当然,在测试条件下,我再说一遍,我希望有人可以确认/纠正我的结果并制定一般规则.

解决方法:

它们的解析方式不同,因此取决于查询,实体关系和其他类似的东西,它们最终可能会成为不同的SQL查询.理想情况下,只要JPQL查询执行相同的操作就应该没有区别,但是应该是it doesn’t always work that way.

推荐的方法是使用显式联接,它还有其他优点,例如在惰性关系上指定JOIN FETCH.这个问题过于关注性能,因为如果其中一个性能更高但给出了相同的结果,那么就没有理由使用速度较慢的了.

无论使用哪种语法,启用SQL日志记录以查看生成的查询都是一种验证应用程序正在执行您期望的查询的好方法.您不能仅仅依靠JPQL,您需要了解和理解您的数据库,所以您不只是使用a.horse_with_no_name喜欢的“混淆层”;)

上一篇:java-休眠的JPQL引发无法输入更新/删除查询


下一篇:java-使用JpaRepository进行动态查询