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


Большинство параметров сортировки баз данных по умолчанию не чувствительны к регистру, но в мире 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. Сужение набора результатов
Сэр, обе ссылки недействительны.
Для простого случая, который вы описываете, посмотрите Restrictions.ilike (), который выполняет поиск без учета регистра.
Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', '%fran%');
List results = crit.list();
Спасибо ... не знал, что ilike существует в Hibernate = 8-)
И для тех, кто ищет эквивалент NHibernate, попробуйте InsensitiveLike ().
Я только что попробовал. и он не ведет себя без учета регистра
Хм ... Предпочтительнее MatchMode.ANYWHERE вместо '%'
Просто будьте осторожны, если вы переключаетесь с Eq на Like, вы также получите включенные подстановочные знаки, такие как подчеркивания в oracle, соответствующие любому символу.
Это не сработает, если вы используете спящий режим в версии ниже 4.1.2. Произошла ошибка github.com/hibernate/hibernate-orm/commit/…, и если вы не можете обновить версию гибернации, вы можете использовать обходной путь Restrictions.ilike (String, Object, MatchMode)
Вам также не нужно использовать подстановочные знаки "%". Вы можете передать 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());
Criteria crit = session.createCriteria(Person.class);
crit.add(Restrictions.ilike('town', 'fran', MatchMode.ANYWHERE);
List results = crit.list();
в чем польза MatchMode.ANYWHERE? он будет соответствовать шаблону в любом месте строки. но будет ли это также поиск без учета регистра. (например, если я ищу льва - он также покажет результат для льва)
Это также можно сделать с помощью примера критерия в пакете 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();
Для гибернации версии 3.6.1 секция для сужения набора результатов - 17.2. Связь