Wayneio
Wayneio

Reputation: 3566

Wildcard Field QueryByExample with JPA Repositories

I have the following JPA Repository:

public interface PostRepository extends JpaRepository<Post, String> {

    List<Post> findAll();

    List<Post> findByExample(Example<Post> example);
}

What I need is to modify the findByExample to take an example but with wildcards on a single field. So in this case, the field "title" needs to be equivalent to an SQL 'like' or 'contains'.

Spring docs show this:

Person person = new Person();                          
person.setFirstname("Dave");                           

ExampleMatcher matcher = ExampleMatcher.matching()     
  .withIgnorePaths("lastname")                         
  .withIncludeNullValues()                             
  .withStringMatcherEnding();                          

Example<Person> example = Example.of(person, matcher);

from https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-methods

but I'm not sure how to customise my interface (assuming a default method) to use this.

Or is there a specific name of a method that spring will autoconfigure with this functionality, such as

List<Post> findByExampleTitleLike(Example<Post> example);

TIA

Upvotes: 1

Views: 2154

Answers (2)

naXa stands with Ukraine
naXa stands with Ukraine

Reputation: 37906

Alternative syntax (shorter).

Service method:

public Page<PersonDto> listPersons(Person probe, Pageable pageable) {
    ExampleMatcher matcher = ExampleMatcher.matching()
        .withIgnoreCase()
        .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);

    final Example<Person> example = Example.of(probe, matcher);
    return personRepository.findAll(example, pageable)
            .map(PersonMapper::convertToDto);
}

Repository:

@Repository
public interface PersonRepository extends JpaRepository<Person, Long>, QueryByExampleExecutor<Person> {
}

Upvotes: 1

Robert Niestroj
Robert Niestroj

Reputation: 16131

I'm doing it like this:

Person person = ...
PageRequest page = ...
ExampleMatcher matcher = ExampleMatcher.matching().withMatcher(
                               "lastname", 
                               ExampleMatcher.GenericPropertyMatcher.of(ExampleMatcher.StringMatcher.CONTAINING).ignoreCase()
                         );
return personRepository.findByExample(Example.of(person, matcher), page).getContent();

SQL 'like' or 'contains' is done by the StringMatcher.CONTAINING. Additionaly i add ignoreCase() to do it case insensitive.

If anyone knows a shorter syntax i would happy to see :)

Upvotes: 2

Related Questions