Использование Hibernate DetachedCriteria для вызова агрегатных функций

#sql #hibernate #hql

#sql #переход в спящий режим #hql

Вопрос:

У меня есть DetachedCriteria , который я использую для поиска в таблице на основе поля имени. Я хочу сделать поиск нечувствительным к регистру, и мне интересно, есть ли способ сделать это без использования HQL. Что-то вроде:

 private void searchByFullName(DetachedCriteria criteria, String searchCriteria) {
        criteria.add(Restrictions.like("fullName", "%"   searchCriteria.toLowerCase()   "%"));
        criteria.addOrder(Order.asc("fullName"));
}
  

Но я хочу убедиться, что он будет игнорировать регистр при выполнении поиска (он должен выполнять поиск как в верхнем, так и в нижнем регистре), поэтому генерируемый им SQL должен выглядеть примерно так:

 SELECT * FROM Student WHERE ? LIKE toLower(FULL_NAME);
  

Комментарии:

1. если у вас в этой таблице много строк, движку придется выполнить сканирование таблицы toLower(FULL_NAME) , чего вы, возможно, не захотите. Одним из вариантов является сохранение всего этого в нижнем регистре или добавление другого столбца, который используется только для поиска, в котором вы сохраняете все это в нижнем регистре.

Ответ №1:

Какую базу данных вы используете? MySQL LIKE не чувствителен к регистру для столбцов CHAR, VARCHAR и TEXT (я полагаю, что то же самое верно для SQL Server).

http://dev.mysql.com/doc/refman/5.5/en/case-sensitivity.html

Если вы используете PostgreSQL, вам захочется использовать оператор ILIKE, поэтому вы захотите использовать Restrictions.ilike(«Полное имя», name).

Ответ №2:

Я вижу два варианта,

Вариант 1:

 private void searchByFullName(DetachedCriteria criteria, String searchCriteria) {
            criteria.add(Restrictions.like("toLower(fullName)", "%"   searchCriteria.toLowerCase()   "%"));
            criteria.addOrder(Order.asc("fullName"));
    }
  

Вариант 2:

 private void searchByFullName(DetachedCriteria criteria, String searchCriteria) {
                criteria.add(Restrictions.sqlRestriction("toLower({alias}.fullName) LIKE '%"   searchCriteria.toLowerCase()   "%'"));
                criteria.addOrder(Order.asc("fullName"));
        }
  

Я не очень оптимистично отношусь к варианту 1. Вариант 2 должен работать наверняка. {alias} является заполнителем, позволяющим Hibernate знать, что ему необходимо добавить соответствующий псевдоним для таблицы при создании SQL. Дополнительная информация http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/criterion/Restrictions.html#sqlRestriction(java.lang.Строка)