是否可以允许查询方法@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}",
}
我想要的是能够看到类似以下路径的内容,其中start
和end
是可选参数,而不是在我的存储库中定义多个方法。
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);
答案 0 :(得分:1)
也许您可以将“ 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);
请注意,在这种情况下,您不应公开其他端点,而应仅公开此默认方法。
答案 1 :(得分:0)
不,目前不支持此功能。如果是的话会有模棱两可的风险。可能存在传入网址可能超过1 @RestResource
的情况。
从Java的角度来解释一下,我们可以定义两种方法:
getPerson(String firstName, int age);
getPerson(String firstName, {Optional} int age, int phoneNumber);
当某人打算调用第二种方法时,会出现问题,而不是提供年龄,而是将其映射到第一种方法,并将phoneNumber作为年龄读取。
答案 2 :(得分:0)
如UserF40所说,这不受支持。我们遇到了类似的问题,并根据提供的可选参数动态构建了查询,从而解决了这个问题。
您可以使用Criteria API来实现此目的,或者通过检查存在的参数来动态构建另一个服务类中的SQL。
答案 3 :(得分:0)
使用 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
答案 4 :(得分:-1)
@Param中有一个“ 必需”参数选项,您可以使用。
@RestResource(path =“ driverAndSpan”,rel =“ byDriverAndSpan”)
列表findByDriverIdAndStartTimeGreaterThanEqualAndEndTimeLessThanEqual(@Param(“ id”)字符串ID,@Param(value =“ start”,必填 = false)日期开始, @Param(value =“ end”,必填 = false)日期结束,可分页可分页);