#java #hibernate #date #criteria #sql-like
#java #гибернация #Дата #критерии #sql-подобный
Вопрос:
Возможно ли выполнить запрос, который проверяет строковое представление экземпляра даты. Например
Restrictions.like("dateField", "%")
для извлечения дат, которые либо имеют строку 12 в день, либо 12 в месяц, либо 12 в год, где «DateField» является экземпляром java.util.Дата
Спасибо
Ответ №1:
У меня была такая же проблема, и вот что я сделал:
Сначала я создал свою собственную реализацию критерия:
public class DateLikeExpression implements Criterion {
private static final long serialVersionUID = 1L;
private String propertyName;
private String value;
public DateLikeExpression(String propertyName, String value) {
this.propertyName = propertyName;
this.value = value;
}
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
if (columns.length != 1) {
throw new HibernateException("Like may only be used with single-column properties");
}
return "to_char(" columns[0] ", 'DD/MM/YYYY HH24:MI') like ?";
}
public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
return new TypedValue[] { new TypedValue(new org.hibernate.type.StringType(),
MatchMode.START.toMatchString(value.toLowerCase()), EntityMode.POJO) };
}
}
Затем я просто использую его, когда объединяю критерии:
criteria.add(new DateLikeExpression("dateColumnName", "26/11%"));
И это все. Обратите внимание, что эта реализация зависит от локали (в данном случае pt_BR) и работает для postgresql, который имеет функцию to_char . Возможно, вам придется немного изменить его для работы с вашим ядром базы данных.
Комментарии:
1. PS: это безопасно для sql-инъекций, в отличие от другого ответа ниже.
2. У меня это не работает. Чего мне может не хватать?
3. @MitalPritmani какую базу данных вы используете? Какой язык? Какие ошибки вы получаете?
4. Я использую PostgreSQL. Locale — IST. Я не получаю никаких ошибок, но это не работает. Я видел в sql by
showsql=true
, что этого критерия вообще нет в запросе, в то время как другие критерии есть!! Я написал именно этот класс и использовал его, как вы предложили. У меня такое же требование — преобразование даты в строку, поэтому может соответствовать некоторым числам.5. @MitalPritmani трудно помочь вам, не глядя на ваш код.
Ответ №2:
Что-то вроде этого
Restrictions.sqlRestriction("month(dateField) = 12");
Restrictions.sqlRestriction("right(year(dateField),2) = 12");
Часть в пределах sqlRestriction зависит от того, какую базу данных вы используете.
Комментарии:
1. Если вы ищете значение, предоставленное пользователем, вы потеряете защиту гибернации от внедрения sql. Вы должны быть очень осторожны в отношении того, как обращаться с вводом. И, скорее всего, средний программист не охватит всю базу. Вы можете использовать функцию приведения в подготовленных запросах HQL для преобразования вашей даты в строку (если база данных поддерживает это), и вы должны быть защищены от внедрения sql.