最近使用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
相关推荐
JPA 使用 Hibernate 作为实现方式JPA + Hibernate + MySQL in Spring Boot注意此项目使用spring-boot 1.4.0版本,不适用于spring-boot 2.0 版本;2.0版本的项目配置可参考:本项目使用IDEA构建,直接导入IDEA即可...
1,这个项目是strut2.0 + hibernate3.0 + jquery.datatables+mysql 5.0实现的 hibernate分页(无排序,搜索,仅仅分页显示),服务器端分页在datatables上展现,有关 datatables的知识请关注它的官网...
好友:可以在指定的日记分类中添加并维护自己的日记 普通用户:可以评论任何可见分类下的日记并维护自己的评论 游客:可以浏览任何可见分类下的所有日记和评论信息 所有人拥有一般使用的权限,例如查看用户资料,...
通过 PostMan 等 RestClient 将待排序的多个数值发给 RestServer,RestServer 对这些数值进行排序,将排序前和排序后的数值存入数据库(可以是MySQL/H2等),并将排序结果返回给 RestClient。如果对 SpringBoot/...
开源中国详解地址:... ... 框架的数据持久层将添加、修改、删除、排序、分页、各种条件的查询封装成通用模块,几乎不用手写SQL。 系统后端和前端全部采用官方的最新稳定版本,可直接应用到企业生产环境。
21.3.1 在mysql.exe程序中设置隔离级别 21.3.2 在应用程序中设置隔离级别 21.4 在应用程序中采用悲观锁 21.4.1 利用数据库系统的独占锁来实现悲观锁 21.4.2 由应用程序实现悲观锁 21.5 利用Hibernate的...
后端和数据库:Java / Spring / Spring MVC / Spring Boot / Hibernate / MySQL。 ○分析了后端系统的需求,确定了向服务器提交数据的功能(登录,搜索,类别排序,立即购买,生成订单,删除订单,确认付款等)。 ...
21.3.1 在mysql.exe程序中设置隔离级别 21.3.2 在应用程序中设置隔离级别 21.4 在应用程序中采用悲观锁 21.4.1 利用数据库系统的独占锁来实现悲观锁 21.4.2 由应用程序实现悲观锁 21.5 利用Hibernate的...
21.3.1 在mysql.exe程序中设置隔离级别 21.3.2 在应用程序中设置隔离级别 21.4 在应用程序中采用悲观锁 21.4.1 利用数据库系统的独占锁来实现悲观锁 21.4.2 由应用程序实现悲观锁 21.5 利用Hibernate的...
21.3.1 在mysql.exe程序中设置隔离级别 21.3.2 在应用程序中设置隔离级别 21.4 在应用程序中采用悲观锁 21.4.1 利用数据库系统的独占锁来实现悲观锁 21.4.2 由应用程序实现悲观锁 21.5 利用Hibernate的...
Java真正智慧的ORM框架,除具有JPA功能外,具有最佳的sql编写模式、独创的缓存翻译、最优化的分页、并提供分组汇总、同比环比、行列转换、树形排序汇总、多数据库适配(oracle\mysql\sqlserver\postgresql\sqlite\db2...
Spring Data JPA的底层是基于Hibernate的,其JpaRepository、PageAndSortingRepository、CrudRepository等组件能够实现快速单表读取与后端分页、排序等功能,所以其便捷性很适合单体式系统的开发。 * 权限管理使用...
1,进销存功能的实现。 2,表头有排序的功能。 3,有统计的功能。 4,美观。 5,系统用户和普通用户的区分和权限。
- 后端:Java,Spring Boot,Hibernate,MySQL - 开发工具:Eclipse,Visual Studio Code,MySQL Workbench 该系统将有一个完整的文档,包括系统需求,设计,实现和测试。该文档将提供详细的说明和演示。 该毕业...
使用的技术:Maven、Spring、Spring Security、Hibernate、JSF、PrettyFaces、PrimeFaces、GMaps4JSF、Jetty、MySQL。 ## 跑步 ## 首先,您需要执行(MySQL)。 然后运行构建和部署: mvn jetty: run ##主要...
struts2.1.8+hibernate3.5.5+spring3.0.2+mysql5.1+jdk1.6 使用SSH整合实现对一个bean的增删改查 实现的功能为: 排序,搜索,分页
本系统主要解决患者在需要就医时的挂号难的问题,以MyEclipse为开发工具,在设计方面采用B/S模式,采用当前最先进、最流行的WEB开发框架和技术之一的SSH框架(Struts + Spring + Hibernate)来完成整个系统的设计,在...