对于初学者,你应该停止使用
@RequestParam并将所有搜索字段放在一个对象中(也许为此使用Travel对象)。然后,你可以使用2个选项来动态构建查询
- 使用
JpaSpecificationExecutor
并写一个Specification
- 使用
QueryDslPredicateExecutor
和使用QueryDSL
编写谓词。
使用
JpaSpecificationExecutor
首先添加
JpaSpecificationExecutor到你的
TravelRepository这会给你一个
findAll(Specification)方法,你可以删除自定义finder方法。
public interface TravelRepository extends JpaRepository<Travel, Long>, JpaSpecificationExecutor<Travel> {}然后,你可以在存储库中创建一个使用的方法,该方法
Specification基本上可以构建查询。请参阅Spring Data JPA 文档。
你唯一需要做的就是创建一个实现
Specification并基于可用字段构建查询的类。使用JPA Criteria API链接构建查询。
public class TravelSpecification implements Specification<Travel> { private final Travel criteria; public TravelSpecification(Travel criteria) { this.criteria=criteria; } public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) { // create query/predicate here. }}最后,你需要修改你的控制器以使用新
findAll方法(我冒昧地将其清理了一下)。
@RequestMapping("/search") public String search(@ModelAttribute Travel search, Pageable pageable, Model model) { Specification<Travel> spec = new TravelSpecification(search); Page<Travel> travels = travelRep.findAll(spec, pageable); model.addObject("page", new PageWrapper(travels, "/search")); return "travels/list";}使用
QueryDslPredicateExecutor
首先添加
QueryDslPredicateExecutor到你的
TravelRepository这会给你一个
findAll(Predicate)方法,你可以删除自定义finder方法。
public interface TravelRepository extends JpaRepository<Travel, Long>, QueryDslPredicateExecutor<Travel> {}接下来,你将实现一种服务方法,该服务方法将使用该Travel对象通过QueryDSL构建谓词。
@Service@Transactionalpublic class TravelService { private final TravelRepository travels; public TravelService(TravelRepository travels) { this.travels=travels; } public Iterable<Travel> search(Travel criteria) { Booleanexpression predicate = QTravel.travel... return travels.findAll(predicate); }}


