Поиск без учета регистра с использованием Hibernate

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

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

Спасибо,

Юваль = 8-)

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
50
0
82 022
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

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

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

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

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

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

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

Я использовал это в прошлом и считаю, что это здорово.

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

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

В критериях гибернации limits.like (...). IgnoreCase ()

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

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

Для гибернации версии 3.6.1 секция для сужения набора результатов - 17.2. Связь

zmf 17.02.2011 01:53

Сэр, обе ссылки недействительны.

Aniket Kulkarni 11.10.2013 13:05
Ответ принят как подходящий

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

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

Спасибо ... не знал, что ilike существует в Hibernate = 8-)

Yuval 23.09.2008 16:51

И для тех, кто ищет эквивалент NHibernate, попробуйте InsensitiveLike ().

Kevin Pullin 02.06.2009 02:43

Я только что попробовал. и он не ведет себя без учета регистра

mR_fr0g 19.06.2009 16:58

Хм ... Предпочтительнее MatchMode.ANYWHERE вместо '%'

Leonel 10.09.2009 16:40

Просто будьте осторожны, если вы переключаетесь с Eq на Like, вы также получите включенные подстановочные знаки, такие как подчеркивания в oracle, соответствующие любому символу.

Richard Dingwall 31.05.2011 20:47

Это не сработает, если вы используете спящий режим в версии ниже 4.1.2. Произошла ошибка github.com/hibernate/hibernate-orm/commit/…, и если вы не можете обновить версию гибернации, вы можете использовать обходной путь Restrictions.ilike (String, Object, MatchMode)

jasiustasiu 25.09.2013 16:15

Вам также не нужно использовать подстановочные знаки "%". Вы можете передать MatchMode (документы для предыдущих выпусков здесь), чтобы указать поиску, как себя вести. Варианты соответствия START, ANYWHERE, EXACT и END.

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

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

Этот комментарий действительно помог. В моем приложении у меня есть следующий код: User u = new User(); u.setUsername(username); List<User> list = HibernateTemplate.findByExample(<u>) для поиска пользователя из базы данных. Но это имя пользователя, если я его даю. Но я хотел написать запрос, который выполняет поиск без учета регистра, поэтому я использовал поиск, показанный SamS, следующим образом: List<User> list = HibernateTemplate.find("from User where upper(username)=?", u.getUsername().toUpperCase());

amit 17.06.2016 09:55

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

в чем польза MatchMode.ANYWHERE? он будет соответствовать шаблону в любом месте строки. но будет ли это также поиск без учета регистра. (например, если я ищу льва - он также покажет результат для льва)

anand krish 10.10.2020 14:26

Это также можно сделать с помощью примера критерия в пакете 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();
}

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

Поскольку 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();

Другие вопросы по теме