dontyer wrote:
I have a problem: when I paging the data with HQL, I need to get the total count of result, but query.list() return all the data, I just went a number.
the HQL is:
select s from com.XXX.XXX.Staff s left join s.rolesSet rs where rs.name =:roleName and s.sex =:sexName
if it's SQL, such as:
select s from table_Staff s left join table_role rs on rs.staffId = s.id where rs.name =:roleName and s.sex =:sexName
I can get the count with:
select count(*) from (select s from table_Staff s left join table_role rs on rs.staffId = s.id where rs.name =:roleName and s.sex =:sexName)
but HQL can't use sub-select at from.
so how can I get the cout of HQL with paramater without do query.list();
nobody knows?
I have a stupid solution:
protected final Integer getQueryResultCount(String hql, Map<String, Object> parameterMap)
throws Exception {
hql = getCountSql(hql,parameterMap, this.getHibernateTemplate().getSessionFactory()); //change to sql
hql = hql.replaceAll(" and", " and ");
return this.getHibernateTemplate().findCountHQL(hql);
}
/**
* 将hql用参数替换后,转成sql语句(change by dong 20130124)
* @param originalHql
* @param parameterMap
* @param sessionFactory
* @return
* @throws Exception
*/
protected String getCountSql(String originalHql, Map<String, Object> parameterMap,
org.hibernate.SessionFactory sessionFactory) throws Exception {
originalHql = packageHQLParamaterData(originalHql, parameterMap); // Fill up the paramaters '= :workes' as '='values''
QueryTranslatorImpl queryTranslator = new QueryTranslatorImpl(originalHql, originalHql,
Collections.EMPTY_MAP, (org.hibernate.engine.SessionFactoryImplementor)sessionFactory);
queryTranslator.compile(Collections.EMPTY_MAP, false);
String sql = queryTranslator.getSQLString().replace("(", "").replace(")", "");
return "SELECT COUNT(*) AS countNumber FROM ( " + sql.replace("or*","or ") + " )";
}
/**
* 替换hql的参数
* @param originalHql
* @param parameterMap
* @return
*/
private String packageHQLParamaterData(String originalHql,
Map<String, Object> parameterMap) {
for(String key:parameterMap.keySet()){
if(parameterMap.get(key) instanceof Integer || parameterMap.get(key) instanceof Long){
originalHql = originalHql.replace(" = :"+key+" ", " = "+parameterMap.get(key)+" ");
originalHql = originalHql.replace(" != :"+key+" ", " != "+parameterMap.get(key)+" ");
originalHql = originalHql.replace(" == :"+key+")", " == "+parameterMap.get(key)+" )");
originalHql = originalHql.replace(" != :"+key+")", " != "+parameterMap.get(key)+" )");
}else if(parameterMap.get(key) instanceof Boolean){
String val = (Boolean)parameterMap.get(key) ? "Y" : "N";
originalHql = originalHql.replace(" = :"+key+" ", " = '"+val+"' ");
originalHql = originalHql.replace(" != :"+key+" ", " != '"+val+"' ");
originalHql = originalHql.replace(" = :"+key+")", " = '"+val+"' )");
originalHql = originalHql.replace(" != :"+key+")", " != '"+val+"' )");
}else{
originalHql = originalHql.replace(" = :"+key+" ", " = '"+(String)parameterMap.get(key)+"'");
originalHql = originalHql.replace(" != :"+key+" ", " != '"+(String)parameterMap.get(key)+"'");
originalHql = originalHql.replace(" like :"+key+" ", " like '"+(String)parameterMap.get(key)+"'");
originalHql = originalHql.replace(" = :"+key+")", " = '"+(String)parameterMap.get(key)+"' )");
originalHql = originalHql.replace(" != :"+key+")", " != '"+(String)parameterMap.get(key)+"' )");
originalHql = originalHql.replace(" like :"+key+")", " like '"+(String)parameterMap.get(key)+"' )");
originalHql = originalHql.replace(" in (:"+key+") ", " in ("+(String)parameterMap.get(key)+")");
}
}
return originalHql;
}
this a bad ideal, Errors all over the place at the beginning, but lucky, it work well now.
so somebody have batter ideal, can share with me, thanks