Specification

受到《领域驱动设计》一书的启发,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)));

最后更新于