問題:
Spring Data JPA 儲存庫支援使用固定、預先定義的查詢建立參數。但是,需要根據使用者提供的欄位動態產生具有任意 AND 子句的查詢。這種方法擴展性很差,並且需要對每種可能的組合進行明確查詢定義。
最佳方法:使用 Criteria API 的規範
Spring Data 提供了利用 Criteria API 建立靈活和動態的規範查詢。透過使用 JpaSpecificationExecutor 擴展儲存庫接口,可以使用各種方法執行規範,包括 findAll。
規範介面:
public interface Specification<T> { Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder); }
範例實作:
public static Specification<Customer> isLongTermCustomer() { return new Specification<Customer>() { public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder builder) { LocalDate date = new LocalDate().minusYears(2); return builder.lessThan(root.get('dateField'), date); } }; } public static Specification<Customer> hasSalesOfMoreThan(MontaryAmount value) { return new Specification<Customer>() { public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder) { // build query here } }; }
用法範例:
List customers = customerRepository.findAll(isLongTermCustomer()); MonetaryAmount amount = new MonetaryAmount(200.0, Currencies.DOLLAR); List<Customer> customers = customerRepository.findAll( where(isLongTermCustomer()).or(hasSalesOfMoreThan(amount)));
複雜規範:
對於複雜規範,您可以在規範中定義自訂方法類別:
public static Specification<WorkInProgress> findByCriteria(final SearchCriteria searchCriteria) { return new Specification<WorkInProgress>() { public Predicate toPredicate(Root<WorkInProgress> root, CriteriaQuery<?> query, CriteriaBuilder cb) { List<Predicate> predicates = new ArrayList<Predicate>(); // Add predicates based on search criteria return cb.and(predicates.toArray(new Predicate[] {})); } }; }
結論:
規範允許動態查詢生成,而不需要明確查詢定義。這種方法具有可擴展性和可擴展性,簡化了靈活且可自訂的查詢的創建。有關更多信息,請參閱 JPA 存儲庫文檔。
以上是如何使用任意 AND 子句建立動態 Spring Data JPA 查詢?的詳細內容。更多資訊請關注PHP中文網其他相關文章!