Строка ввода = Джон 5 (записи с именем Джон и 5 в телефоне)
Здесь предикаты с использованием вашего ввода выглядят следующим образом:
Predicate predicateForName = criteriaBuilder.like(
criteriaBuilder.lower(TeacherRoot.get("name")),
"%john 5%");
//other predicates
Predicate predicateForPhone = criteriaBuilder.like(
TeacherRoot.get("phoneNumber"),
"%John 5%");
Вы пытаетесь найти записи, в которых name like "%john 5%"
и phoneNumber like "%John 5%"
.
Вы должны разбить входную строку на слова и использовать предикаты для каждого слова.
public List<Teacher> searchByString(String str) {
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Teacher> criteriaQuery = criteriaBuilder.createQuery(Teacher.class);
Root<Teacher> TeacherRoot = criteriaQuery.from(Teacher.class);
Predicate predicateFinal = getPredicateByInput(str, criteriaBuilder);
criteriaQuery.where(predicateFinal);
return em.createQuery(criteriaQuery).getResultList();
}
public Predicate getPredicateByInput(String input, CriteriaBuilder criteriaBuilder) {
String[] words = input.split(" ");
Predicate predicate = null;
for(String word : words) {
Predicate wordPredicate = getPredicateByWord(word, criteriaBuilder);
if(predicate == null)
predicate = wordPredicate;
else
predicate = criteriaBuilder.or(predicate, wordPredicate);
}
Objects.requireNonNull(predicate, "Null predicate is not allowed. Invalid input string '" + input + "'");
return predicate;
}
private Predicate getPredicateByWord(String word, CriteriaBuilder criteriaBuilder) {
Predicate predicateForName = criteriaBuilder.like(
criteriaBuilder.lower(TeacherRoot.get("name")),
"%" + word.toLowerCase() + "%");
Predicate predicateForFam = criteriaBuilder.like(
criteriaBuilder.lower(TeacherRoot.get("fam")),
"%" + word.toLowerCase() + "%");
Predicate predicateForOtch = criteriaBuilder.like(
criteriaBuilder.lower(TeacherRoot.get("otch")),
"%" + word.toLowerCase() + "%");
Predicate predicateForPhone = criteriaBuilder.like(
TeacherRoot.get("phoneNumber"),
"%" + word + "%");
Predicate predicateForDate = criteriaBuilder.like(
TeacherRoot.get("dateOfBirth").as(String.class),
"%" + word + "%");
return criteriaBuilder.or(
predicateForName,
predicateForFam,
predicateForOtch,
predicateForPhone,
predicateForDate);
}
Предложение Like имеет большой вес, поэтому следует избегать избыточных предикатов