转:[url]http://blog.csdn.net/explorering/article/details/1196397[/url]
按位与运算(&)在许多数据库中都是支持的,遗憾的是,Hibernate 3在HQL中不支持&运算,如果你写了如下的HQL:
where a.id & :mask = :target
则Hibernate报错:exception: unexpected char: '&'.
如何解决此问题?方法是利用Hibernate支持的自定义SQLFunction,定义一个bitand(a,b)的SQLFunction,然后,自己写一个解释器,生成a & b的SQL语句。
要实现一个自定义的SQLFunction,必须实现SQLFunction接口:
package com.js.dialect;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.QueryException;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;
/**
* <p>
* Title:BitAndFunction
* </p>
* <p>
* Description:
* </p>
*
* @author js
* @version
* @since
*/
public class BitAndFunction implements SQLFunction {
public Type getReturnType(Type type, Mapping mapping) {
return Hibernate.INTEGER;
}
public boolean hasArguments() {
return true;
}
public boolean hasParenthesesIfNoArguments() {
return true;
}
public String render(List args, SessionFactoryImplementor factory)
throws QueryException {
if (args.size() != 2) {
throw new IllegalArgumentException(
"BitAndFunction requires 2 arguments!");
}
return args.get(0).toString() + " & " + args.get(1).toString();
}
}
然后,根据使用的数据库方言,派生一个自定义的CustomSQLDialect:
package com.js.dialect;
import org.hibernate.dialect.MySQLInnoDBDialect;
/**
* <p>
* Title:CustomSQLDialect
* </p>
* <p>
* Description:
* </p>
*
* @author js
* @version
* @since
*/
public class CustomSQLDialect extends MySQLInnoDBDialect {
/**
*
*/
public CustomSQLDialect() {
super();
registerFunction("bitand", new BitAndFunction());
}
}
设定函数名为bitand,参数和返回值均为Hibernate.LONG,现在,用CustomSQLDialect替换配置文件中的设置,然后修改HQL:
where bitand(a.id, :mask) = :target
编译,运行,观察Hibernate的SQL输出,执行不成功!不认识"bitand"!
按位与运算(&)在许多数据库中都是支持的,遗憾的是,Hibernate 3在HQL中不支持&运算,如果你写了如下的HQL:
where a.id & :mask = :target
则Hibernate报错:exception: unexpected char: '&'.
如何解决此问题?方法是利用Hibernate支持的自定义SQLFunction,定义一个bitand(a,b)的SQLFunction,然后,自己写一个解释器,生成a & b的SQL语句。
要实现一个自定义的SQLFunction,必须实现SQLFunction接口:
package com.js.dialect;
import java.util.List;
import org.hibernate.Hibernate;
import org.hibernate.QueryException;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.Mapping;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;
/**
* <p>
* Title:BitAndFunction
* </p>
* <p>
* Description:
* </p>
*
* @author js
* @version
* @since
*/
public class BitAndFunction implements SQLFunction {
public Type getReturnType(Type type, Mapping mapping) {
return Hibernate.INTEGER;
}
public boolean hasArguments() {
return true;
}
public boolean hasParenthesesIfNoArguments() {
return true;
}
public String render(List args, SessionFactoryImplementor factory)
throws QueryException {
if (args.size() != 2) {
throw new IllegalArgumentException(
"BitAndFunction requires 2 arguments!");
}
return args.get(0).toString() + " & " + args.get(1).toString();
}
}
然后,根据使用的数据库方言,派生一个自定义的CustomSQLDialect:
package com.js.dialect;
import org.hibernate.dialect.MySQLInnoDBDialect;
/**
* <p>
* Title:CustomSQLDialect
* </p>
* <p>
* Description:
* </p>
*
* @author js
* @version
* @since
*/
public class CustomSQLDialect extends MySQLInnoDBDialect {
/**
*
*/
public CustomSQLDialect() {
super();
registerFunction("bitand", new BitAndFunction());
}
}
设定函数名为bitand,参数和返回值均为Hibernate.LONG,现在,用CustomSQLDialect替换配置文件中的设置,然后修改HQL:
where bitand(a.id, :mask) = :target
编译,运行,观察Hibernate的SQL输出,执行不成功!不认识"bitand"!