I have a search filter - a username and two start and end dates. How can I make selects for these fields using repositories?

@Service public class ResolutionServiceDefault implements ResolutionService { @Autowired private ResolutionRepository resolutionRepository; @Override public List<Resolution> findAllFilter(String user, Date start, Date end) { if(user!=null)... if(start!=null)... if(end!=null)... //выполнить запрос по полям которые не null return .....; } } @Repository public interface ResolutionRepository extends JpaRepository<Resolution, Long> { List<Resolution> findAllByStatus(int status); List<Resolution> findAll();//String user, Date start, Date end } 

1 answer 1

Solved similar problems using the Specification interface:

 public class ResolutionSpecs { public static Specification<Resolution> isActualUser(String user) { return new Specification<Resolution>() { public Predicate toPredicate(Root<Resolution> r, CriteriaQuery<?> cq, CriteriaBuilder cb) { return cb.equal(r.get(_Resolution.user), user); } }; } public static Specification<Resolution> isSomeDateAfter(Date start) { return new Specification<Resolution>() { public Predicate toPredicate(Root<Resolution> r, CriteriaQuery<?> cq, CriteriaBuilder cb) { return cb.greater(r.get(_Resolution.someDate), start); } }; } public static Specification<Resolution> isSomeDateBefore(Date end) { return new Specification<Resolution>() { public Predicate toPredicate(Root<Resolution> r, CriteriaQuery<?> cq, CriteriaBuilder cb) { return cb.lower(r.get(_Resolution.someDate), end); } }; } } @Repository public interface ResolutionRepository extends JpaRepository<Resolution, Long>, JpaSpecificationExecutor<Resolution> { } @Service public class ResolutionService { private final ResolutionRepository repository; @Autowired public ResolutionService(ResolutionRepository repository) { this.repository = repository; } public List<Resolution> findByUserAndSomeDateBetween(String user, Date start, Date end) { Specification<Resolution> sp = null; if (user != null) { sp = Specifications.where(ResolutionSpecs.isActualUser(user)); } if (start != null) { sp = (sp == null ? Specifications.where(ResolutionSpecs.isSomeDateAfter(start)) : sp.and(ResolutionSpecs.isSomeDateAfter(start))); } if (end != null) { sp = (sp == null ? Specifications.where(ResolutionSpecs.isSomeDateBefore(end)) : sp.and(ResolutionSpecs.isSomeDateBefore(end))); } return repository.findAll(sp); } } 

Documentation is here .

It may also be an option to use the library to generate SQL queries, such as JOOQ, but I do not have combat experience with it. Documentation is here . An example is here .

  • @NicolasChabanovsky I wrote about the three methods in the form in which they should be implemented in the interface described above - what is not a specific example? - Maksim
  • @NicolasChabanovsky understood, I will correct - Maksim
  • @NicolasChabanovsky done - Maksim