注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

骇客归来

ぁ枫あ

 
 
 

日志

 
 

在HQL中绕过中文乱码查询  

2007-02-12 12:27:07|  分类: Hibernate |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 在HQL中绕过中文乱码查询

  以下是我在hibernate查询(通过Spring)中碰到的一个小问题及其解决方法,简单但实用,希望也有益于各同友。 

  在用hibernate查询中假如用到一个带中文的参数,如:
String hql  =   " from Customer user where 1=1 and userr.mc like '%惠止南国%' " ;
Session session  =  getHibernateTemplate().getSessionFactory().openSession(); // Spring
Transaction tx  =  session.beginTransaction();
Query qry  =  session.createQuery(sql);
List returnList  =  qry.list();
tx.commit();
session.close();


  在执行过程中在eclpise的console台中可以看到hibernate经过底层将其译成SQL后成了:

  select ... from Customer user  where 1=1 and userr.hh like '%??????%'

  的样子。我试过将其以不同的方式编码,可是都没有将其最终以正确的结果返回。暂且不谈此方法应该如何写,我主要是想说通过用另外一种查询方法:在HQL中绑定参数预编译机制来解决这个乱码问题。

  参数绑定机制有如下优点:
  a 安全感,防止恶意用户非法调用DB的存储过程
  b 利用底层数据库编译SQL的功能,提高数据库查询性能。预编译是指底层数据库系统只能编译SQL语句一次,把编译出来的可执行代码保存在缓存中,如果有多次执行相同的SQL语句,不需要重新编译,只要从缓存中读取即可。

  将上面的执行过程改成如下:
List params  =   new  ArrayList();
String hql  =   " from Customer user where 1=1 and userr.mc like ? " ;
params.add( " '% "   +  form.get( " zdmlmc " ).toString()  +   " %' " );
Object[] objs  =  params.toArray();
Session session  =  getHibernateTemplate().getSessionFactory().openSession();
Transaction tx  =  session.beginTransaction();
Query qry  =  session.createQuery(sql);
if  (objs  ==   null )  //  判断是否确认参数名称
{
  if (objs.length > 0 )
   for  ( int  i  =   0 ; i  <  objs.length; i ++ )
   qry.setParameter(i, objs[i]);
}
List returnList  =  qry.list();
tx.commit();
session.close();


  这样就可以看到在console中最后所执行的SQL:

  select ... from Customer user  where 1=1 and userr.mc like '%惠止南国%'

  在上面中有这样的语句:

  qry.setParameter(i, objs[i]);

  这是属于按参数位置绑定中的绑定任意的参数类型。

  org.hibernate.Query的参数绑定形式可以分为

  1 按参数位置绑定

  2 按参数位置绑定

  Query绑定参数类型可以分为:

  1 参数与持久化类实体绑定
Customer cus  =   new  Customer();
   // 省略其它初始化
   // 以下是按参数位置绑定
  query.setEntity( " pa_name " ,customer);
   //  or
        // 按参数位置绑定
  query.setEntity(index_location,customer); // index_location是其在HQL中的下标位置,从0开始


  2 绑定任意类型参数

  上面中的qry.setParameter(...)就是这种类型,我们qry.setParameter(i, objs[i]);中是省略了第三个参数即Hibernate映射类型,如:

  qry.setParameter(i, objs[i],Hibernate.STRING);

  对于有些参数,Hibernate能根据参数值的java类型推断出对应的映射类型,此时不再要在setParameter()中显式指定映射类型。如上

  3 将命名参数与一个对象属性绑定

  setProperties()方法

  个人觉得这个跟ORM技术的ibatis中的SQLMAP有些许相似。它是用setProperties()方法。如:
String hql  =   " from Customer user where 1=1 and userr.mc like :sna " ;
Customer cus  =   new  Customer();
cus.setMc( " 惠止南国 " );
Session session  =  getHibernateTemplate().getSessionFactory().openSession();
Transaction tx  =  session.beginTransaction();
List returnList  =  session.createQuery(sql).setProperties(cus).list();
tx.commit();
session.close();

Attention:对于日期型数据不能用setProperties()方法通过实体来绑定。
  评论这张
 
阅读(513)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017