10-03
08

解决Hibernate 3不支持 "&" 运算的SQL语句

按位与运算(&)在许多数据库中都是支持的,遗憾的是,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"!



文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: 运算 hibernate3 SQL
相关日志:
评论: 0 | 引用: 0 | 查看次数: 509
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭