Likeexpression的构造函数均受保护,因此这不是一个可行的选择。同样,它也有自己的问题。
我和一位同事创建了一个效果很好的补丁。补丁的要点是,对于使用MatchMode的Likeexpression构造函数,我们转义了特殊字符。对于使用Character(转义字符)的构造函数,我们假设用户自己转义了特殊字符。
我们还参数化了转义字符,以确保它们使用或引号字符之类的字符时不会破坏SQL查询。
package org.hibernate.criterion;import org.hibernate.Criteria;import org.hibernate.HibernateException;import org.hibernate.dialect.Dialect;import org.hibernate.engine.TypedValue;public class Likeexpression implements Criterion { private final String propertyName; private final String value; private final Character escapeChar; protected Likeexpression( String propertyName, Object value) { this(propertyName, value.toString(), (Character) null); } protected Likeexpression( String propertyName, String value, MatchMode matchMode) { this( propertyName, matchMode.toMatchString( value .toString() .replaceAll("!", "!!") .replaceAll("%", "!%") .replaceAll("_", "!_")), '!' ); } protected Likeexpression( String propertyName, String value, Character escapeChar) { this.propertyName = propertyName; this.value = value; this.escapeChar = escapeChar; } public String toSqlString( Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { Dialect dialect = criteriaQuery.getFactory().getDialect(); String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, propertyName ); if ( columns.length != 1 ) { throw new HibernateException( "Like may only be used with single-column properties" ); } String lhs = lhs(dialect, columns[0]); return lhs + " like ?" + ( escapeChar == null ? "" : " escape ?" ); } public TypedValue[] getTypedValues( Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException { return new TypedValue[] { criteriaQuery.getTypedValue( criteria, propertyName, typedValue(value) ), criteriaQuery.getTypedValue( criteria, propertyName, escapeChar.toString() ) }; } protected String lhs(Dialect dialect, String column) { return column; } protected String typedValue(String value) { return value; }}如果您想知道lhs和typedValue方法的用途,新的Ilikeexpression应该回答这些问题。
package org.hibernate.criterion;import org.hibernate.dialect.Dialect;public class Ilikeexpression extends Likeexpression { protected Ilikeexpression( String propertyName, Object value) { super(propertyName, value); } protected Ilikeexpression( String propertyName, String value, MatchMode matchMode) { super(propertyName, value, matchMode); } protected Ilikeexpression( String propertyName, String value, Character escapeChar) { super(propertyName, value, escapeChar); } @Override protected String lhs(Dialect dialect, String column) { return dialect.getLowercaseFunction() + '(' + column + ')'; } @Override protected String typedValue(String value) { return super.typedValue(value).toLowerCase(); }}此后,剩下的唯一事情就是使Restrictions使用以下新类:
public static Criterion like(String propertyName, Object value) { return new Likeexpression(propertyName, value);}public static Criterion like(String propertyName, String value, MatchMode matchMode) { return new Likeexpression(propertyName, value, matchMode);}public static Criterion like(String propertyName, String value, Character escapeChar) { return new Likeexpression(propertyName, value, escapeChar);}public static Criterion ilike(String propertyName, Object value) { return new Ilikeexpression(propertyName, value);}public static Criterion ilike(String propertyName, String value, MatchMode matchMode) { return new Ilikeexpression(propertyName, value, matchMode);}public static Criterion ilike(String propertyName, String value, Character escapeChar) { return new Ilikeexpression(propertyName, value, escapeChar);}编辑:哦,是的。这适用于Oracle。但是,我们不确定其他数据库。



