我想選擇與In-Criterion和Hibernate Criteria API不區分大小寫的項目。 例如Ignorecase for In Criterion
Criteria crit = session.createCriteria(Item.class);
crit.add(Restrictions.in("prop", valueList).ignoreCase());
不幸的是Criterion類沒有ignoreCase方法。 HQL不是一種替代方案。
我想選擇與In-Criterion和Hibernate Criteria API不區分大小寫的項目。 例如Ignorecase for In Criterion
Criteria crit = session.createCriteria(Item.class);
crit.add(Restrictions.in("prop", valueList).ignoreCase());
不幸的是Criterion類沒有ignoreCase方法。 HQL不是一種替代方案。
找Restrictions.in()
(InExpression
)返回的標準類的源代碼,並創建另一個是類似的,但變換值列表爲小寫的所有元素,併產生像SQL查詢:
lower(prop) in (...)
我實現了我自己的InExpression,它忽略了大小寫。 它與hibernate-core-3.6.10.Final中的InExpresion幾乎相同。 唯一的區別是'下(..)'。
import java.util.ArrayList;
import org.hibernate.Criteria;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.InExpression;
import org.hibernate.engine.TypedValue;
import org.hibernate.type.CompositeType;
import org.hibernate.type.Type;
import org.hibernate.util.StringHelper;
public class InExpressionIgnoringCase implements Criterion {
private final String propertyName;
private final Object[] values;
public InExpressionIgnoringCase(final String propertyName, final Object[] values) {
this.propertyName = propertyName;
this.values = values;
}
public String toSqlString(final Criteria criteria, final CriteriaQuery criteriaQuery) throws HibernateException {
final String[] columns = criteriaQuery.findColumns(this.propertyName, criteria);
final String[] wrappedLowerColumns = wrapLower(columns);
if (criteriaQuery.getFactory().getDialect().supportsRowValueConstructorSyntaxInInList() || columns.length <= 1) {
String singleValueParam = StringHelper.repeat("lower(?), ", columns.length - 1) + "lower(?)";
if (columns.length > 1)
singleValueParam = '(' + singleValueParam + ')';
final String params = this.values.length > 0 ? StringHelper.repeat(singleValueParam + ", ",
this.values.length - 1) + singleValueParam : "";
String cols = StringHelper.join(", ", wrappedLowerColumns);
if (columns.length > 1)
cols = '(' + cols + ')';
return cols + " in (" + params + ')';
} else {
String cols = " (" + StringHelper.join(" = lower(?) and ", wrappedLowerColumns) + "= lower(?)) ";
cols = this.values.length > 0 ? StringHelper.repeat(cols + "or ", this.values.length - 1) + cols : "";
cols = " (" + cols + ") ";
return cols;
}
}
public TypedValue[] getTypedValues(final Criteria criteria, final CriteriaQuery criteriaQuery)
throws HibernateException {
final ArrayList<TypedValue> list = new ArrayList<TypedValue>();
final Type type = criteriaQuery.getTypeUsingProjection(criteria, this.propertyName);
if (type.isComponentType()) {
final CompositeType actype = (CompositeType) type;
final Type[] types = actype.getSubtypes();
for (int j = 0; j < this.values.length; j++) {
for (int i = 0; i < types.length; i++) {
final Object subval = this.values[j] == null ? null : actype.getPropertyValues(this.values[j],
EntityMode.POJO)[i];
list.add(new TypedValue(types[i], subval, EntityMode.POJO));
}
}
} else {
for (int j = 0; j < this.values.length; j++) {
list.add(new TypedValue(type, this.values[j], EntityMode.POJO));
}
}
return list.toArray(new TypedValue[list.size()]);
}
@Override
public String toString() {
return this.propertyName + " in (" + StringHelper.toString(this.values) + ')';
}
private String[] wrapLower(final String[] columns) {
final String[] wrappedColumns = new String[columns.length];
for (int i = 0; i < columns.length; i++) {
wrappedColumns[i] = "lower(" + columns[i] + ")";
}
return wrappedColumns;
}
}
用法:
final Criteria crit = session.createCriteria(Item.class);
crit.add(new InExpressionIgnoringCase("prop", array));
替代的方法是使用一個sqlRestriction。因此,您可以將您的值轉換爲逗號分隔的小寫字符串,然後再調用。
crit.add(Restrictions.sqlRestriction("lower({alias}.prop) in (" + q + ")"));
但是,您的查詢參數將不得不進行消毒。可以使用disjunction。
Junction j = Restrictions.disjunction();
for (String prop: props) {
j.add(Restrictions.eq("prop", prop).ignoreCase());
}
crit.add(j);
.add(Restrictions.sqlRestriction("upper({alias}.COLUMN_NAME) = upper(?)", VALUE_TO_COMPARE, Hibernate.STRING))
爲我工作。