【问题标题】:How to avoid left outer join when finding by embedded object id in Spring Data JPA在 Spring Data JPA 中通过嵌入对象 id 查找时如何避免左外连接
【发布时间】:2020-05-05 05:13:19
【问题描述】:

我有两个实体类:

class One {
    Long id;

    <Other properties>

    @ManyToOne
    Two two;
}

class Two {
    Long id;

    <Other properties>
}

现在,在OneRepository,我有一个方法:

One findByIdAndTwoId(Long oneId, Long twoId);

当调用该方法时,发送到数据库的查询是:

    select
        <properties>
    from
        one one0_ 
    left outer join
        two two1_ 
            on one0_.two_id=two1_.id 
    where
        and one0_.id=? 
        and two1_.id=?

而我希望它是以下形式:

    select
        <properties>
    from
        one one0_ 
    where
        and one0_.id=? 
        and one0_.two_id=?

有什么办法可以做到吗?请帮忙。

编辑:

如果我使用如下所述的条件查询,则生成的查询没有连接子句。

        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<One> cq = cb.createQuery(One.class);
        Root<One> oneRoot = cq.from(One.class);
        cq.select(oneRoot).where(
                cb.equal(oneRoot.get("id"), oneId),
                cb.equal(oneRoot.get("two").get("id"), twoId)
        );
        TypedQuery<One> query = entityManager.createQuery(cq);
        return query.getSingleResult();

【问题讨论】:

  • 没有。但是为什么你认为第二个查询比第一个更好呢?你检查执行计划了吗?
  • 我在想,当所需的一切都在一个表中时,为什么要与另一个表连接。
  • 当然,但这就是 Hibernate 的工作原理。
  • 但是如果我有一个方法One findByIdAndTwo(Long oneId, Two two); 那么查询中就没有加入。
  • 对于findByIdAndTwo,无需加入,因为您正在传递子obj,但对于findByIdAndTwoId,您通过TwoId 进行查询意味着Two 实体的id 字段,因此它加入@987654333 @entity 在 where 子句中使用 two.id

标签: postgresql hibernate spring-boot spring-data-jpa


【解决方案1】:

使用 JPA 原生查询

使用@Query 注解,您可以通过将 nativeQuery 标志设置为 true 来执行本机查询。

@Query(value = "select * from one o where o.id=?1 and o.two_id=?2", nativeQuery = true)
One findByIdAndTwoId(Long oneId, Long twoId);

【讨论】:

  • 不想使用原生查询。我喜欢仅在使用任何其他方式无法获得所需结果的情况下使用本机查询。
  • 我认为没有其他方法可以使用 Spring data JPA 来做到这一点。如果你发现任何东西请告诉我
  • 而且使用原生查询一点也不坏。
  • 不是一个坏习惯,只是我不喜欢在我的代码中使用魔法刺痛。
猜你喜欢
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2019-07-16
  • 2012-02-02
  • 1970-01-01
相关资源
最近更新 更多