Подтвердить что ты не робот

Нечувствительный к регистру поиск с использованием Hibernate

Я использую Hibernate для ORM моего приложения Java в базе данных Oracle (не то, что имеет дело с производителем базы данных, мы можем переключиться на другую базу данных в один прекрасный день), и я хочу получить объекты из базы данных в соответствии с предоставленными пользователем строки. Например, при поиске людей, если пользователь ищет людей, которые живут в "fran", я хочу иметь возможность дать ее людям в Сан-Франциско.

SQL не мой сильный костюм, и я предпочитаю Hibernate Criteria код здания для жестко закодированных строк, как есть. Может ли кто-нибудь указать мне в правильном направлении, как это сделать в коде, и если это невозможно, как выглядит жесткий код SQL?

Спасибо,

Yuval = 8 -)

4b9b3361

Ответ 1

В простом случае, который вы описываете, посмотрите на Restrictions.ilike(), который делает поиск без учета регистра.

Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', '%fran%');
List results = crit.list();

Ответ 2

Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', 'fran', MatchMode.ANYWHERE);
List results = crit.list();

Ответ 3

Если вы используете Spring HibernateTemplate для взаимодействия с Hibernate, вот как вы будете делать поиск без учета регистра на адрес электронной почты пользователя:

getHibernateTemplate().find("from User where upper(email)=?", emailAddr.toUpperCase());

Ответ 4

Обычный подход к игнорированию случая - это преобразование значений базы данных и входного значения в верхний или нижний регистр - результирующий sql будет иметь что-то вроде

select f.name from f where TO_UPPER(f.name) like '%FRAN%'

В спящих критериях ограничений .like(...). ignoreCase()

Я больше знаком с Nhibernate, поэтому синтаксис может быть не точным на 100%

для получения дополнительной информации см. pro hibernate 3 extract и спящий режим docs 15.2. Сужение набора результатов

Ответ 6

Большинство сопоставлений базы данных по умолчанию не чувствительны к регистру, но в мире SQL Server его можно установить в экземпляре, базе данных и уровне столбца.

Ответ 7

Вы можете посмотреть, как использовать компас с оболочкой над lucene.

http://www.compass-project.org/

Добавив несколько аннотаций к объектам домена, вы достигнете такого уровня.

Compass предоставляет простой API для работы с Lucene. Если вы знаете, как использовать ORM, тогда вы будете чувствовать себя как дома с помощью Compass с простыми операциями для сохранения и удаления и запроса.

С самого сайта. "Основываясь на вершине Lucene, Compass упрощает общие шаблоны использования Lucene, такие как поиск в стиле Google, индексы, а также более продвинутые концепции, такие как кеширование и индексирование (sub indexs). Compass также использует встроенные оптимизации для параллельных коммитов и слияния".

Я использовал это в прошлом, и я нахожу это замечательным.

Ответ 8

Это также можно сделать, используя критерий Example, в пакете org.hibernate.criterion.

public List findLike(Object entity, MatchMode matchMode) {
    Example example = Example.create(entity);
    example.enableLike(matchMode);
    example.ignoreCase();
    return getSession().createCriteria(entity.getClass()).add(
            example).list();
}

Еще один способ, которым я считаю полезным выполнить вышеизложенное.

Ответ 9

Начиная с Hibernate 5.2 session.createCriteria устарела. Ниже приведено решение с использованием JPA 2 CriteriaBuilder. Он использует like и upper:

    CriteriaBuilder builder = session.getCriteriaBuilder();
    CriteriaQuery<Person> criteria = builder.createQuery(Person.class);
    Root<Person> root = criteria.from(Person.class);

    Expression<String> upper = builder.upper(root.get("town"));
    criteria.where(builder.like(upper, "%FRAN%"));

    session.createQuery(criteria.select(root)).getResultList();