Условное объединение Spring Data JPA - PullRequest
0 голосов
/ 07 июня 2018

Я создал приложение Spring Boot.Это REST-сервер.Поскольку сервисы REST используются клиентом Angular, в некоторых случаях у меня довольно большой запрос, в котором много 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 на основе наличия параметра.

1 Ответ

0 голосов
/ 08 июня 2018

Существуют различные варианты, которые могут соответствовать требованиям:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...