Hibernate QBC对汉字进展排序
Hibernate QBC对汉字进行排序
通常在Criteria查询时,是通过criteria.addOrder(Order.asc("name"))排序;
但是默认情况下是不支持GBK格式,所以汉字无法按照拼音进行排序。下面的方法是重写Hibernate Order方法实现对汉字排序。
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);
}
}
但是如果用上面的方法之后。数字的排序就达不到预期的目的了,需要利用反射对java类的属性进行判断,查看其类型:
Class<?> c = object.getClass().getField(str).getType();
System.out.println(c.getName());
通过判断类型的不同进行部不同的处理。
详情参考:http://raywithu.iteye.com/blog/1139332
通常在Criteria查询时,是通过criteria.addOrder(Order.asc("name"))排序;
但是默认情况下是不支持GBK格式,所以汉字无法按照拼音进行排序。下面的方法是重写Hibernate Order方法实现对汉字排序。
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);
}
}
但是如果用上面的方法之后。数字的排序就达不到预期的目的了,需要利用反射对java类的属性进行判断,查看其类型:
Class<?> c = object.getClass().getField(str).getType();
System.out.println(c.getName());
通过判断类型的不同进行部不同的处理。
详情参考:http://raywithu.iteye.com/blog/1139332