Поиск пользователей по заданному фильтру с игнорированием пустых параметров

Добавьте JpaSpecificationExecutor<User> в репозиторий и собирайте AND из непустых условий. При отсутствии условий вернётся весь список пользователей.

Короткий ответ

Что ответить на собеседовании

Добавьте JpaSpecificationExecutor<User> в репозиторий и собирайте AND из непустых условий. При отсутствии условий вернётся весь список пользователей.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо реализовать метод searchByCriteria в классе UserService, который ищет пользователей в базе согласно переданному объекту UserFilter. При построении запроса следует:

  • пропускать поля фильтра, которые равны null или пустой строке;
  • если заданы оба поля (firstName и lastName) – применять их совместно;
  • использовать возможности Spring Data JPA через UserRepository;
  • вернуть список всех найденных сущностей User.
public class UserService {

  private final UserRepository userRepo;

  public List<User> searchByCriteria(UserFilter filter) {
  }
}

@RequiredArgsConstructor
@Getter
public class UserFilter {

  private final String firstName;
  private final String lastName;
}

@Entity
public class User {

  @Id
  private Long id;
  private String firstName;
  private String lastName;
}

public interface UserRepository extends JpaRepository<User, Long> {
}

Ответ

Добавьте JpaSpecificationExecutor<User> в репозиторий и собирайте AND из непустых условий. При отсутствии условий вернётся весь список пользователей.

public interface UserRepository extends JpaRepository<User, Long>,
        JpaSpecificationExecutor<User> {}

public List<User> searchByCriteria(UserFilter filter) {
    Objects.requireNonNull(filter);
    Specification<User> spec = (root, query, cb) -> {
        List<Predicate> predicates = new ArrayList<>();
        if (filter.getFirstName() != null && !filter.getFirstName().isEmpty())
            predicates.add(cb.equal(root.get("firstName"), filter.getFirstName()));
        if (filter.getLastName() != null && !filter.getLastName().isEmpty())
            predicates.add(cb.equal(root.get("lastName"), filter.getLastName()));
        return cb.and(predicates.toArray(new Predicate[0]));
    };
    return userRepo.findAll(spec);
}

Predicate здесь из Criteria API используемой версии JPA; остальные типы — стандартные Java и Spring Data JPA. Пробельные строки не считаются пустыми по исходному условию. Сравнение точное, регистр зависит от БД. UserService также нужен конструктор для final userRepo.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее