【问题标题】:Spring Data JPA conditional joinSpring Data JPA 条件连接
【发布时间】:2018-11-17 14:40:52
【问题描述】:

我创建了一个 Spring Boot 应用程序。它是一个 REST 服务器。 因为 Angular 客户端使用 REST 服务,所以在某些视图中,我有一个相当大的查询,其中我有很多 LEFT 和 INNER JOIN 来检查可选的搜索字段。

不幸的是,所有搜索字段都是可选的,因此并不总是需要 JOIN。 现在我正在使用这样的存储库:

    @RestResource(exported = false)
    @Transactional(readOnly = true)
    // @formatter:off
    @Query("SELECT t FROM Ticket t " + "JOIN Account a ON a.username=t.createdBy "
            + "LEFT JOIN User u ON u.account=a "
            + "LEFT JOIN Customer c ON t.customer=c " + "LEFT JOIN Account ca ON c.account=ca " + "JOIN t.checkPoint ck "
            + "LEFT JOIN t.customer c1 " + "LEFT JOIN t.transitCertificate tc " + "WHERE "
            + "(:allFieldsSearch IS NULL OR (t.code LIKE CONCAT('%',:allFieldsSearch,'%') OR t.licensePlate1 LIKE CONCAT('%',:allFieldsSearch,'%') OR t.licensePlate2 LIKE CONCAT('%',:allFieldsSearch,'%') OR c.name LIKE CONCAT('%',:allFieldsSearch,'%') )) "
            + "AND (:code IS NULL OR t.code LIKE CONCAT('%',:code,'%')) "
            + "AND (:licensePlate IS NULL OR (t.licensePlate1 LIKE CONCAT(:licensePlate,'%') OR t.licensePlate2 LIKE CONCAT(:licensePlate,'%'))) "
            + "AND (:transitCertificate IS NULL OR tc.code=:transitCertificate) "
            + "AND (:customer IS NULL OR c1.name LIKE CONCAT('%',:customer,'%')) "
            + "AND (:checkPoint IS NULL OR ck.name LIKE CONCAT('%',:checkPoint,'%')) "
            + "AND (:agent IS NULL OR (a.type='USER' AND u.name LIKE CONCAT('%',:agent,'%')) OR (a.type='CUSTOMER' AND c.name LIKE CONCAT('%',:agent,'%'))) "
            + "AND (:paid IS NULL OR t.paid=:paid) " + "AND (:ecommerce IS NULL OR (:ecommerce=true AND t.salesChannel='ECOMMERCE')) "
            + "AND (:checkedMedia IS NULL OR (:checkedMedia=false AND t.checkedMedia=false AND medias > 0)) "
            + "AND (:checkedLicensePlate IS NULL OR (:checkedLicensePlate=false AND t.checkedLicensePlate=false AND ((t.engineEuroLevel1>3 OR (t.engineEuroLevel1=3 AND t.particulateFilter1=true))  OR (t.engineEuroLevel2>3 OR (t.engineEuroLevel2=3 AND t.particulateFilter2=true))))  ) "
            + "AND (:warning IS NULL OR (warning=:warning)) " 
            + "AND (:color IS NULL OR (color=:color)) "
            + "AND (:status IS NULL OR t.status=:status) "
            + "AND (:from IS NULL OR t.entryDate>=:from) " 
            + "AND (:until IS NULL OR t.entryDate<=:until) "
            + "AND (:fromCreatedDate IS NULL OR t.createdDate>=:fromCreatedDate) "
            + "AND (:untilCreatedDate IS NULL OR t.createdDate<=:untilCreatedDate) "
            // the customer cannot see canceled tickets
            + "AND (CAST(t.status as string) <>?#{hasRole('ROLE_CUSTOMER') ? 'CANCELED':''}) "
            + "AND (ca.username=?#{principal.username} OR t.createdBy LIKE ?#{hasRole('ROLE_CUSTOMER') ? principal.username:'%'})")
    // @formatter:on
    public Page<Ticket> search(@Param("allFieldsSearch") String allFieldsSearch, @Param("code") String code,
            @Param("licensePlate") String licensePlate, @Param("transitCertificate") String transitCertificate,
            @Param("customer") String customer, @Param("agent") String agent, @Param("checkPoint") String checkPoint,
            @Param("paid") Boolean paid, @Param("ecommerce") Boolean ecommerce, @Param("checkedMedia") Boolean checkedMedia,
            @Param("checkedLicensePlate") Boolean checkedLicensePlate, @Param("warning") Boolean warning, @Param("color") String color,
            @Param("status") TicketStatus status, @Param("from") Instant from, @Param("until") Instant until,
            @Param("fromCreatedDate") Instant fromCreatedDate, @Param("untilCreatedDate") Instant untilCreatedDate, Pageable pageable);

代码很方便。它很紧凑,不需要其他任何东西。 不幸的是,即使用户没有设置任何参数,我也会在这里进行所有 JOIN。

我想知道是否有一种方法可以根据参数的存在来创建条件 JOIN。

【问题讨论】:

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


    【解决方案1】:

    有多种选择可能符合要求:

    【讨论】:

      猜你喜欢
      • 2021-04-20
      • 2020-08-30
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多