Spring Data Jpa 多个 findBy 查询的一种方法

问题描述

我有这个 JobPosting 类和这个实体的存储库接口。我希望能够搜索 JobPosting 类的公司、技能、职位和城市字段的所有组合。我知道的唯一方法是在存储库界面中创建不同的方法。例如,要按城市和标题搜索,我需要创建一个名为 findByCityIdAndTitleContaining(Long id,String title) 的方法。为了按技能和职称搜索,我需要创建一个名为 LfindBySkillsIdAndTitleContaining(Long id,String title) 的方法。问题是如果我为每种可能性创建不同的方法,就会有太多的方法。有没有更好的办法?

实体(我这里没有包括 get set 方法):

@Entity
public class JobPosting
{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;
    @ManyToOne
    private Company company;
    private Date publishedAt;
    private String title,description;
    private boolean isActive;
    @ManyToOne
    private City city;
    @ManyToMany
    @JoinTable(name="job_posting_skill",joinColumns=@JoinColumn(name="job_posting_id"),inverseJoinColumns=@JoinColumn(name="skill_id"))
    private Set<Skill> skills;
}

存储库:

package app.repository;

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import app.entity.JobPosting;

public interface JobPostingRepository extends JpaRepository<JobPosting,Long>
{
    Page<JobPosting> findAll(Pageable pageable);
    List<JobPosting> findByCompanyId(long companyId);
    List<JobPosting> findByTitleContaining(String title);
    List<JobPosting> findBySkillsId(Long id);
    List<JobPosting> findByCityId(Long id);
}

解决方法

Spring Data 提供了可以满足您需求的 JpaSpecificationExecutor。

https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaSpecificationExecutor.html

List<T>     findAll(Specification<T> spec)
Returns all entities matching the given Specification.

规范有一个谓词方法:

interface Specification<T> {
    Predicate toPredicate(Root<T> root,CriteriaQuery query,CriteriaBuilder cb);
}

它有一个 CriteriaBuilder,所以理论上你仍然需要定义你需要匹配的内容,但是你不必创建多个 findByXYZ。

为了能够使用 findAll(Specification),您的存储库需要扩展 org.springframework.data.jpa.repository.JpaSpecificationExecutor<T>:

用法示例:

https://www.baeldung.com/spring-data-criteria-queries