解决Hibernate中MySQL的中文排序

http://raywithu.iteye.com/blog/1139332 转载请注明出处


最近使用mysql做一个交易网站,使用hibernate作为持久化框架。

当我使用hibernate的Order进行排序的时候,杯具发生了。中文给我乱排了。

mysql中如果需要正常按照中文排序,其中一种处理方法是

 

Sql代码   收藏代码
  1. SELECT *  
  2. FROM BZ_COMPANY  
  3. ORDER BY CONVERT( COMPANY_NAME USING GBK ) ASC  

 

 

可问题是这样就脱离hibernate了。本打算使用QBC做一些公共的方法的。

然后就去看了下hibernate中Order的实现。

 

hibernate的Order:

 

Java代码   收藏代码
  1. //$Id: Order.java,v 1.1 2011/05/29 18:11:15 Surui Exp $  
  2. package org.hibernate.criterion;  
  3.   
  4. import java.io.Serializable;  
  5. import java.sql.Types;  
  6.   
  7. import org.hibernate.Criteria;  
  8. import org.hibernate.HibernateException;  
  9. import org.hibernate.engine.SessionFactoryImplementor;  
  10. import org.hibernate.type.Type;  
  11.   
  12. /** 
  13.  * Represents an order imposed upon a <tt>Criteria</tt> result set 
  14.  * @author Gavin King 
  15.  */  
  16. public class Order implements Serializable {  
  17.   
  18.     private boolean ascending;  
  19.     private boolean ignoreCase;  
  20.     private String propertyName;  
  21.       
  22.     public String toString() {  
  23.         return propertyName + ' ' + (ascending?"asc":"desc");  
  24.     }  
  25.       
  26.     public Order ignoreCase() {  
  27.         ignoreCase = true;  
  28.         return this;  
  29.     }  
  30.   
  31.     /** 
  32.      * Constructor for Order. 
  33.      */  
  34.     protected Order(String propertyName, boolean ascending) {  
  35.         this.propertyName = propertyName;  
  36.         this.ascending = ascending;  
  37.     }  
  38.   
  39.     /** 
  40.      * Render the SQL fragment 
  41.      * 
  42.      */  
  43.     public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)   
  44.     throws HibernateException {  
  45.         String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);  
  46.         Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);  
  47.         StringBuffer fragment = new StringBuffer();  
  48.         for ( int i=0; i<columns.length; i++ ) {  
  49.             SessionFactoryImplementor factory = criteriaQuery.getFactory();  
  50.             boolean lower = ignoreCase && type.sqlTypes( factory )[i]==Types.VARCHAR;  
  51.             if (lower) {  
  52.                 fragment.append( factory.getDialect().getLowercaseFunction() )  
  53.                     .append('(');  
  54.             }  
  55.             fragment.append( columns[i] );  
  56.             if (lower) fragment.append(')');  
  57.             fragment.append( ascending ? " asc" : " desc" );  
  58.             if ( i<columns.length-1 ) fragment.append(", ");  
  59.         }  
  60.         return fragment.toString();  
  61.     }  
  62.   
  63.     /** 
  64.      * Ascending order 
  65.      * 
  66.      * @param propertyName 
  67.      * @return Order 
  68.      */  
  69.     public static Order asc(String propertyName) {  
  70.         return new Order(propertyName, true);  
  71.     }  
  72.   
  73.     /** 
  74.      * Descending order 
  75.      * 
  76.      * @param propertyName 
  77.      * @return Order 
  78.      */  
  79.     public static Order desc(String propertyName) {  
  80.         return new Order(propertyName, false);  
  81.     }  
  82.   
  83. }  

 

 

重点就在toSqlString上了,QBC的Criteria也是toSqlString产生对应sql的,所以只要在这里做手脚,就能达到效果。

当然,不赞成直接改源码。

 

然后就有了GBKOrder:

 

Java代码   收藏代码
  1. package comm;  
  2.   
  3. import java.sql.Types;  
  4.   
  5. import org.hibernate.Criteria;  
  6. import org.hibernate.HibernateException;  
  7. import org.hibernate.criterion.CriteriaQuery;  
  8. import org.hibernate.criterion.Order;  
  9. import org.hibernate.engine.SessionFactoryImplementor;  
  10. import org.hibernate.type.Type;  
  11.   
  12. public class GBKOrder extends Order {  
  13.     private String encoding = "GBK";  
  14.     private boolean ascending;  
  15.     private boolean ignoreCase;  
  16.     private String propertyName;  
  17.   
  18.     @Override  
  19.     public String toString() {  
  20.         return "CONVERT( " + propertyName + " USING " + encoding + " ) " + (ascending ? "asc" : "desc");  
  21.     }  
  22.   
  23.     @Override  
  24.     public Order ignoreCase() {  
  25.         ignoreCase = true;  
  26.         return this;  
  27.     }  
  28.   
  29.     /** 
  30.      * Constructor for Order. 
  31.      */  
  32.     protected GBKOrder(String propertyName, boolean ascending) {  
  33.         super(propertyName, ascending);  
  34.         this.propertyName = propertyName;  
  35.         this.ascending = ascending;  
  36.     }  
  37.   
  38.     /** 
  39.      * Constructor for Order. 
  40.      */  
  41.     protected GBKOrder(String propertyName, String dir) {  
  42.         super(propertyName, dir.equalsIgnoreCase("ASC") ? true : false);  
  43.         ascending = dir.equalsIgnoreCase("ASC") ? true : false;  
  44.         this.propertyName = propertyName;  
  45.         this.ascending = ascending;  
  46.     }  
  47.   
  48.     /** 
  49.      * Render the SQL fragment 
  50.      *  
  51.      */  
  52.     @Override  
  53.     public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {  
  54.         String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);  
  55.         Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);  
  56.         StringBuffer fragment = new StringBuffer();  
  57.         for (int i = 0; i < columns.length; i++) {  
  58.             SessionFactoryImplementor factory = criteriaQuery.getFactory();  
  59.             boolean lower = ignoreCase && type.sqlTypes(factory)[i] == Types.VARCHAR;  
  60.             if (lower) {  
  61.                 fragment.append(factory.getDialect().getLowercaseFunction()).append('(');  
  62.             }  
  63.             fragment.append("CONVERT( " + columns[i] + " USING " + encoding + " )");  
  64.             if (lower)  
  65.                 fragment.append(')');  
  66.             fragment.append(ascending ? " asc" : " desc");  
  67.             if (i < columns.length - 1)  
  68.                 fragment.append(", ");  
  69.         }  
  70.         return fragment.toString();  
  71.     }  
  72.   
  73.     /** 
  74.      * Ascending order 
  75.      *  
  76.      * @param propertyName 
  77.      * @return Order 
  78.      */  
  79.     public static Order asc(String propertyName) {  
  80.         return new GBKOrder(propertyName, true);  
  81.     }  
  82.   
  83.     /** 
  84.      * Descending order 
  85.      *  
  86.      * @param propertyName 
  87.      * @return Order 
  88.      */  
  89.     public static Order desc(String propertyName) {  
  90.         return new GBKOrder(propertyName, false);  
  91.     }  
  92. }  

 

 

使用例子:

 

Java代码   收藏代码
  1. public PageControl findPage(final PageControl pageControl, final Object bean) {  
  2.     try {  
  3.         final Class clazz = bean.getClass();  
  4.         List data = (List) this.getHibernateTemplate().execute(new HibernateCallback() {  
  5.             public Object doInHibernate(Session session) throws HibernateException, SQLException {  
  6.                 Criteria criteria = session.createCriteria(clazz);  
  7.                 criteria.add(Example.create(bean)  
  8.                         .ignoreCase()  
  9.                         .enableLike(MatchMode.ANYWHERE));  
  10.                 if (pageControl != null) {  
  11.                     int start = pageControl.getStart();  
  12.                     int limit = pageControl.getLimit();  
  13.                     criteria.setFirstResult(start);  
  14.                     criteria.setMaxResults(limit);  
  15.                     String sort = pageControl.getSort();  
  16.                     String dir = pageControl.getDir();  
  17.                     if (sort != null && dir != null) {  
  18.                         criteria.addOrder(dir.equalsIgnoreCase("ASC") ? GBKOrder.asc(sort) : GBKOrder.desc(sort));  
  19.                     }  
  20.                 }  
  21.                 return criteria.list();  
  22.             }  
  23.         });  
  24.         Long totalCount = getTotalCount(bean);  
  25.         PageControl rt = new PageControl();  
  26.         rt.setData(data);  
  27.         rt.setTotalCount(totalCount);  
  28.         return rt;  
  29.     } catch (RuntimeException e) {  
  30.         log.error("find page failed", e);  
  31.         throw e;  
  32.     }  
  33. }  

当然,你有需要的话,不必写死GBK




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值