簡體   English   中英

帶有可選@Param 的 Spring 數據查詢方法

[英]Spring Data Query Method with Optional @Param

是否可以允許查詢方法 @Params 是可選的,特別是在 Spring Data REST 的情況下?

例如,我想將一個非常相似的搜索綁定到相同的資源路徑。 現在要做到這一點,我需要如下內容:

@RestResource(path = "driver", rel = "byDriver")
List<Bar> findByDriverId(@Param("id") String id, Pageable pageable);

@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(@Param("id") String id, @Param("start") Date start,
        @Param("end") Date end, Pageable pageable);

這給了我:

byDriver: {
  href: "http://localhost:8080/foo/search/driver{?id,page,size,sort}",
},
byDriverAndSpan: {
  href: "http://localhost:8080/foo/search/driverAndSpan{?id,start,end,page,size,sort}",
}

想要的是能夠看到類似於以下路徑的內容,其中startend是可選參數,而不是在我的 Repository 中定義多個方法。

byDriverAndSpan: {
  href: "http://localhost:8080/foo/search/driverAndSpan{?id,*start,*end,page,size,sort}",
}

這可能看起來像:

@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(@Param("id") String id, @Param(value = "start", optional = true) Date start,
        @Param(value = "end", optional = true) Date end, Pageable pageable);

也許您可以將“main”函數定義為default ,該函數將委托給其他函數。 像這樣的東西

@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
default List<Bar> findByDriverIdAndOptionalStartTimeGreaterThanEqualAndOptionalEndTimeLessThanEqual(@Param("id") String id, @Param(value = "start", optional = true) Date start,
        @Param(value = "end", optional = true) Date end, Pageable pageable) {
   if(start != null && end != null) {
      return findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(id, start, end, pageable);
   }
   return findByDriverId(id, pageable);
}

我覺得你甚至可以使用Optional作為參數類型,然后你可以使用函數重載

@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")
default List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(
@Param("id") String id, @Param(value = "start") Optional<Date> start,
        @Param(value = "end") Optional<Date> end, Pageable pageable) {
   if (!start.isEmpty() && !end.isEmpty()) {
      return findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(id, start.get(), end.get(), pageable);
   }
   return findByDriverId(id, pageable);
}

List<Bar> findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(String id, Date start, Date end, Pageable pageable);

請注意,在這種情況下,您不應公開其他端點,而應僅公開此默認方法。

不,目前不支持此功能。 如果是這樣,就會有歧義的風險。 可能存在傳入 url 匹配超過 1 個@RestResource

為了從 Java 的角度進行解釋,假設我們可以定義兩種方法:

getPerson(String firstName, int age);

getPerson(String firstName, {Optional} int age, int phoneNumber);

當有人打算調用第二種方法時會出現問題,而不是提供年齡,而是映射到第一種方法,並將 phoneNumber 作為年齡讀取。

正如 UserF40 所說,這不受支持。 我們遇到了類似的問題,並通過根據提供的 Optional 參數動態構建查詢來解決它。

您可以使用 Criteria API 來實現這一點,或者通過檢查存在哪些參數在另一個服務類中動態構建 SQL。

使用 org.springframework.data.jpa.repository.JpaSpecificationExecutor;`

第 1 步:在您的 JPA 存儲庫中實現JpaSpecificationExecutor

前任:

public interface TicketRepo extends JpaRepository<Ticket, Long>, JpaSpecificationExecutor<Ticket> {

第 2 步現在根據可選參數獲取票證,您可以使用 CriteriaBuilder 構建規范查詢

前任:

public Specification<Ticket> getTicketQuery(Integer domainId, Calendar startDate, Calendar endDate, Integer gameId, Integer drawId) {
    return (root, query, criteriaBuilder) -> {
        List<Predicate> predicates = new ArrayList<>();

        predicates.add(criteriaBuilder.equal(root.get("domainId"), domainId));
        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createdAt"), startDate));
        predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createdAt"), endDate));

        if (gameId != null) {
            predicates.add(criteriaBuilder.equal(root.get("gameId"), gameId));
        }

        return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
    };
}

第 3 步:將 Specification 實例傳遞給 jpaRepo.findAll(specification),它將返回您的實體對象列表(運行示例中的票證)

ticketRepo.findAll(specification); // Pass output of function in step 2 to findAll

@Param 中有一個“ required ”參數選項可供您使用。

@RestResource(path = "driverAndSpan", rel = "byDriverAndSpan")

列出 findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(@Param("id") String id, @Param(value = "start", required = false) 日期開始,@Param(value = "end", required = false) 日期結束,Pageable pageable);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM