`
raywithu
  • 浏览: 24680 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

解决Hibernate中MySQL的中文排序

阅读更多

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

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

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

 

SELECT *
FROM BZ_COMPANY
ORDER BY CONVERT( COMPANY_NAME USING GBK ) ASC

 

 

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

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

 

hibernate的Order:

 

//$Id: Order.java,v 1.1 2011/05/29 18:11:15 Surui Exp $
package org.hibernate.criterion;

import java.io.Serializable;
import java.sql.Types;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;

/**
 * Represents an order imposed upon a <tt>Criteria</tt> result set
 * @author Gavin King
 */
public class Order implements Serializable {

	private boolean ascending;
	private boolean ignoreCase;
	private String propertyName;
	
	public String toString() {
		return propertyName + ' ' + (ascending?"asc":"desc");
	}
	
	public Order ignoreCase() {
		ignoreCase = true;
		return this;
	}

	/**
	 * Constructor for Order.
	 */
	protected Order(String propertyName, boolean ascending) {
		this.propertyName = propertyName;
		this.ascending = ascending;
	}

	/**
	 * Render the SQL fragment
	 *
	 */
	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
	throws HibernateException {
		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
		StringBuffer fragment = new StringBuffer();
		for ( int i=0; i<columns.length; i++ ) {
			SessionFactoryImplementor factory = criteriaQuery.getFactory();
			boolean lower = ignoreCase && type.sqlTypes( factory )[i]==Types.VARCHAR;
			if (lower) {
				fragment.append( factory.getDialect().getLowercaseFunction() )
					.append('(');
			}
			fragment.append( columns[i] );
			if (lower) fragment.append(')');
			fragment.append( ascending ? " asc" : " desc" );
			if ( i<columns.length-1 ) fragment.append(", ");
		}
		return fragment.toString();
	}

	/**
	 * Ascending order
	 *
	 * @param propertyName
	 * @return Order
	 */
	public static Order asc(String propertyName) {
		return new Order(propertyName, true);
	}

	/**
	 * Descending order
	 *
	 * @param propertyName
	 * @return Order
	 */
	public static Order desc(String propertyName) {
		return new Order(propertyName, false);
	}

}

 

 

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

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

 

然后就有了GBKOrder:

 

package comm;

import java.sql.Types;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.CriteriaQuery;
import org.hibernate.criterion.Order;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;

public class GBKOrder extends Order {
	private String encoding = "GBK";
	private boolean ascending;
	private boolean ignoreCase;
	private String propertyName;

	@Override
	public String toString() {
		return "CONVERT( " + propertyName + " USING " + encoding + " ) " + (ascending ? "asc" : "desc");
	}

	@Override
	public Order ignoreCase() {
		ignoreCase = true;
		return this;
	}

	/**
	 * Constructor for Order.
	 */
	protected GBKOrder(String propertyName, boolean ascending) {
		super(propertyName, ascending);
		this.propertyName = propertyName;
		this.ascending = ascending;
	}

	/**
	 * Constructor for Order.
	 */
	protected GBKOrder(String propertyName, String dir) {
		super(propertyName, dir.equalsIgnoreCase("ASC") ? true : false);
		ascending = dir.equalsIgnoreCase("ASC") ? true : false;
		this.propertyName = propertyName;
		this.ascending = ascending;
	}

	/**
	 * Render the SQL fragment
	 * 
	 */
	@Override
	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
		StringBuffer fragment = new StringBuffer();
		for (int i = 0; i < columns.length; i++) {
			SessionFactoryImplementor factory = criteriaQuery.getFactory();
			boolean lower = ignoreCase && type.sqlTypes(factory)[i] == Types.VARCHAR;
			if (lower) {
				fragment.append(factory.getDialect().getLowercaseFunction()).append('(');
			}
			fragment.append("CONVERT( " + columns[i] + " USING " + encoding + " )");
			if (lower)
				fragment.append(')');
			fragment.append(ascending ? " asc" : " desc");
			if (i < columns.length - 1)
				fragment.append(", ");
		}
		return fragment.toString();
	}

	/**
	 * Ascending order
	 * 
	 * @param propertyName
	 * @return Order
	 */
	public static Order asc(String propertyName) {
		return new GBKOrder(propertyName, true);
	}

	/**
	 * Descending order
	 * 
	 * @param propertyName
	 * @return Order
	 */
	public static Order desc(String propertyName) {
		return new GBKOrder(propertyName, false);
	}
}

 

 

使用例子:

 

	public PageControl findPage(final PageControl pageControl, final Object bean) {
		try {
			final Class clazz = bean.getClass();
			List data = (List) this.getHibernateTemplate().execute(new HibernateCallback() {
				public Object doInHibernate(Session session) throws HibernateException, SQLException {
					Criteria criteria = session.createCriteria(clazz);
					criteria.add(Example.create(bean)
							.ignoreCase()
							.enableLike(MatchMode.ANYWHERE));
					if (pageControl != null) {
						int start = pageControl.getStart();
						int limit = pageControl.getLimit();
						criteria.setFirstResult(start);
						criteria.setMaxResults(limit);
						String sort = pageControl.getSort();
						String dir = pageControl.getDir();
						if (sort != null && dir != null) {
							criteria.addOrder(dir.equalsIgnoreCase("ASC") ? GBKOrder.asc(sort) : GBKOrder.desc(sort));
						}
					}
					return criteria.list();
				}
			});
			Long totalCount = getTotalCount(bean);
			PageControl rt = new PageControl();
			rt.setData(data);
			rt.setTotalCount(totalCount);
			return rt;
		} catch (RuntimeException e) {
			log.error("find page failed", e);
			throw e;
		}
	}

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

 

附上效果图:


 

http://www.surui.cc/archives/78

 

 

  • 大小: 37.2 KB
  • 大小: 37.2 KB
5
2
分享到:
评论
2 楼 Aubergine_kang 2011-12-09  
感谢楼主的分享,好东东  
1 楼 zjshan 2011-08-03  
不错的资料,O(∩_∩)O~

相关推荐

    Hibernate的MySql查询.rar

    在Java企业级开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作。本文将深入探讨在使用Hibernate进行MySQL查询时的一些关键知识点,以帮助开发者更好地理解和应用这些技术。 ...

    struts+hibernate+mysql站内邮件系统

    本系统利用Java技术栈中的Struts、Hibernate和MySQL三大组件进行构建,实现了用户登录注册、邮件管理、联系人等功能,为用户提供了一个高效、便捷的内部通信环境。 Struts作为MVC(模型-视图-控制器)框架,负责...

    网上书城系统(Struts+Hibernate+Mysql)-project

    在本网上书城系统中,Hibernate用于管理数据库交互,将Java对象(如书籍、订单等)与MySQL数据库中的表格对应起来。通过Hibernate,开发者可以避免编写大量的SQL语句,提高开发效率,并实现数据持久化的灵活管理和...

    jsp源码网上书城系统(Struts+Hibernate+Mysql)

    ### jsp源码网上书城系统(Struts+Hibernate+Mysql)知识点解析 #### 一、项目概述 该项目是一款基于JSP技术栈构建的网上书城系统,主要采用Struts框架进行前端展示与控制,利用Hibernate作为持久层框架实现数据访问...

    SpringMVC + Hibernate4 + JQuery + Ajax + MySQL整合

    在本项目中,MySQL作为存储数据的主要平台,与Hibernate4配合,提供数据持久化支持。 **项目结构与示例** 项目中的14个示例涵盖了从基础到进阶的多个方面,可能包括: 1. Hello World示例,展示SpringMVC的基本...

    spring-boot-jpa-hibernate-demo:Spring Boot中的JPA + Hibernate + MySQL

    JPA 使用 Hibernate 作为实现方式JPA + Hibernate + MySQL in Spring Boot注意此项目使用spring-boot 1.4.0版本,不适用于spring-boot 2.0 版本;2.0版本的项目配置可参考:本项目使用IDEA构建,直接导入IDEA即可...

    strut2.0 + hibernate3.0 + jquery.datatables+mysql 5.0实现的 hibernate分页

    1,这个项目是strut2.0 + hibernate3.0 + jquery.datatables+mysql 5.0实现的 hibernate分页(无排序,搜索,仅仅分页显示),服务器端分页在datatables上展现,有关 datatables的知识请关注它的官网...

    hibernate中文参考文档 V3.2

    4. **Query与Criteria API**:介绍如何使用HQL(Hibernate Query Language)和Criteria API进行复杂的数据查询,包括条件、排序、分组和连接等。 5. **Caching**:探讨了Hibernate的缓存机制,包括第一级缓存...

    hibernate 开发文档发布

    3.1.x版本中,Hibernate已经包含了对主流数据库的方言支持,如MySQL、Oracle、PostgreSQL等,使得代码更具移植性。 八、性能优化 在3.1.x版本中,Hibernate对性能进行了多方面的优化,包括延迟加载(Lazy Loading)...

    hibernate所需jar包

    在Hibernate中,你需要这个驱动来建立与MySQL数据库的连接,以便进行数据交互。 3. **javassist-3.12.0.GA.jar**: Javassist是一个开源的分析、转换和生成Java字节码的类库。Hibernate使用它在运行时动态地修改类和...

    基于Java S2SH框架开发的网上订餐管理系统 (struts2,hibernate4,spring3)

    Java S2SH框架是Java Web开发中常用的一种技术栈,由Struts2、Hibernate4和Spring3三个组件组成。这三个组件分别负责不同的职责,共同构建了一个功能强大的MVC(Model-View-Controller)架构的网上订餐管理系统。 1...

    hibernate-release-5.4.25.Final_Hibernate5.4.25_hibernate所需jar包_源

    总之,Hibernate 5.4.25为Java开发者提供了强大的数据持久化解决方案,通过合理的jar包配置和应用,可以极大地提升开发效率,降低项目维护成本。在理解和掌握其核心特性的基础上,灵活运用到实际项目中,将有助于...

    spring+struts+hibernate+mysql博客系统(源码+数据库+文档)

    好友:可以在指定的日记分类中添加并维护自己的日记 普通用户:可以评论任何可见分类下的日记并维护自己的评论 游客:可以浏览任何可见分类下的所有日记和评论信息 所有人拥有一般使用的权限,例如查看用户资料,...

    hibernate 配置属性参数详情(全)

    例如,如果你使用的是MySQL,你可以设置为`org.hibernate.dialect.MySQL5Dialect`。 2. **hibernate.show_sql**:如果设置为`true`,Hibernate将在控制台上打印出执行的所有SQL语句,这对于调试非常有用。 3. **...

    Hibernate 参数配置详解

    - **描述**:强制 Hibernate 按照被更新数据的主键为 SQL 更新排序,以减少高并发系统中事务的死锁。 - **取值**:`true` 或 `false`。 - **示例**:`hibernate.order_updates=true` ##### 11. 统计数据生成 ...

    hibernate[1].cfg.xml中配置信息详解

    **取值**:支持各种数据库方言的全限定类名,例如`org.hibernate.dialect.MySQL5Dialect`。 ##### 2. `hibernate.show_sql` **用途**:启用或禁用在控制台上显示执行的SQL语句。对于开发阶段来说,这是一个非常...

    用 Java/SpringBoot/Hibernate 实现一个 RestServer,支持对整型类型的数值进行排序

    通过 PostMan 等 RestClient 将待排序的多个数值发给 RestServer,RestServer 对这些数值进行排序,将排序前和排序后的数值存入数据库(可以是MySQL/H2等),并将排序结果返回给 RestClient。如果对 SpringBoot/...

    Hibernate 框架测试版本

    Hibernate 支持多种数据库,如MySQL、Oracle、PostgreSQL等,并提供了丰富的API和工具。 2. **配置Hibernate** 在使用Hibernate之前,你需要在项目中配置Hibernate。这通常包括创建`hibernate.cfg.xml`配置文件,...

    struts2+spring3+hibernate3+jquery+flexigrid+mysql实例

    在这个实例中,Hibernate 可能用于将Java对象映射到MySQL数据库表,简化数据库操作。 4. **jQuery**:jQuery 是一个轻量级的JavaScript库,简化了DOM操作、事件处理、动画效果和Ajax交互。在Web前端,jQuery 可能...

Global site tag (gtag.js) - Google Analytics