简体   繁体   中英

Spring Data Jpa One method for multiple findBy Queries

I have this JobPosting class and a repository interface for this entity. I wanna be able to search for all combinations of company, skills, title and city fields of JobPosting class. The only way I know is creating a different method in repository interface . For instance for searching by city and title i need to create a method named findByCityIdAndTitleContaining(Long id,String title). For searching by skills and title i need to create a method named LfindBySkillsIdAndTitleContaining(Long id,String title). The problem is if i create different method for each possibility there will be too many methods. Is there any better way ?

Entity (I didn't include get set methods here):

@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;
}

Repository:

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 provides JpaSpecificationExecutor which can fit your requirements.

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.

A Specification has a predicate method:

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

It has a CriteriaBuilder, so in theory you will still need to define what exactly you need to match for, however you wont have to create multiple findByXYZ.

To be able to use findAll(Specification), your repository needs to extend org.springframework.data.jpa.repository.JpaSpecificationExecutor<T>:

Example of usage:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM