受到《领域驱动设计》一书的启发,Spring Data JPA 提供了根据 Criteria 查询的 API。
要启用 Specification,你的 Repository 需要继承 JpaSpecificationExecutor
:
public interface StudentRepository extends JpaRepository<Student, Long>, JpaSpecificationExecutor<Student> {}
JpaSpecificationExecutor
提供了一些预定义方法的 Specification 查询接口,例如:
List<T> findAll(Specification<T> spec);
要使用 Specification 查询,最佳实践是,实现一个专门的类用来保存你设计的 Specification:
package cn.com.iamddch.sia1;
import org.springframework.data.jpa.domain.Specification;
public class StudentSpecs {
public static Specification<Student> isAge24() {
return (root, query, builder) -> {
return builder.equal(root.get("age"), 24);
};
}
}
这里给出了一个很简单的判断年龄是否是 24 岁的 Specification。
要使用 Specification 查询:
@GetMapping("/all")
public List<Student> getAllStudent() {
return studentRepository.findAll(StudentSpecs.isAge24());
}
[
{
"id": 2,
"name": "Vanille",
"age": 24
},
{
"id": 3,
"name": "Lightning",
"age": 24
}
]
但是 Specification 有什么优势呢?用之前的方法都能轻松实现它的功能吧。
Specification 的主要优势是,它提供了一些胶水代码的默认实现,方便用户组合现有 Specification 来构建复杂的查询:
MonetaryAmount amount = new MonetaryAmount(200.0, Currencies.DOLLAR);
List<Customer> customers = customerRepository.findAll(
isLongTermCustomer().or(hasSalesOfMoreThan(amount)));