/* ================================================================== * Created [2009-4-27 下午11:32:55] by Jon.King * ================================================================== * TSS * ================================================================== * mailTo:jinpujun@hotmail.com * Copyright (c) Jon.King, 2009-2012 * ================================================================== */ package com.jinhe.tss.component.support.persistence.pagequery; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.persistence.EntityManager; import javax.persistence.Query; import org.apache.commons.collections.CollectionUtils; import com.jinhe.tss.core.exception.BusinessException; import com.jinhe.tss.core.persistence.QueryCondition; import com.jinhe.tss.core.util.BeanUtil; import com.jinhe.tss.core.util.EasyUtils; import com.jinhe.tss.core.util.MacrocodeCompiler; /** * 分页条件查询基类 */ public abstract class PaginationQuery { static final String[] COMMON_IGNORE_PROPERTIES = new String[] { "page", "conditionMacrocodes", "class", "ignoreProperties", "order" }; protected EntityManager em; protected String ql; // SQL 或 HQL 语句,里面带宏,传入时不带order by protected MacrocodeQueryCondition condition; public PaginationQuery(EntityManager em, String ql, MacrocodeQueryCondition condition) { if ( em == null ) throw new BusinessException("em不能为空"); if ( condition == null ) throw new BusinessException("分页条件查询对象不能为空"); if ( EasyUtils.isNullOrEmpty(ql) ) throw new BusinessException("查询语句不能为空"); this.em = em; this.ql = ql; this.condition = condition; } /** * <p> * 执行分页查询,获取分页结果及相关信息 * </p> * @return */ public PageInfo getResultList() { Set<String> ignores = condition.getIgnoreProperties(); CollectionUtils.addAll(ignores, COMMON_IGNORE_PROPERTIES); Map<String, Object> properties = BeanUtil.getProperties(condition, ignores); // 过滤空参数、无效参数对应的宏代码 Map<String, Object> macrocodes = condition.getConditionMacrocodes(); for ( Iterator<String> it = macrocodes.keySet().iterator(); it.hasNext(); ) { String key = it.next(); if (key.startsWith("${") && key.endsWith("}")) { String name = key.substring(2, key.length() - 1); Object value = properties.get(name); if ( QueryCondition.isValueNullOrEmpty(value) ) { it.remove(); } } } // 解析带了宏定义的QL语句 String queryQl = MacrocodeCompiler.run(ql, macrocodes); PageInfo page = condition.getPage(); page.setTotalRows(getTotalRows(queryQl, properties)); // 获取当前页数据记录集 int firstResult = page.getFirstResult(); if (firstResult >= 0) { // 添加HQL中order by 语句 appendOrderBy(); Query query = createQuery(queryQl); query.setFirstResult(firstResult); query.setMaxResults(page.getPageSize()); // 为查询语句设置相应的参数 setProperties4Query(query, properties); page.setItems( query.getResultList() ); } return page; } /* 添加HQL中order by 语句 */ private void appendOrderBy(){ if ( condition.getOrderByFields() == null ) return; String orderByFiledContent = ""; for ( String field : condition.getOrderByFields() ) { if( EasyUtils.isNullOrEmpty(field) ) continue; if ( orderByFiledContent.length() > 0 ) { orderByFiledContent += ", "; } orderByFiledContent += field; } if ( orderByFiledContent.length() > 0 ) { ql += " order by " + orderByFiledContent; } } /** * <p> * 为查询语句设置相应的参数 * </p> * @param query 查询 * @param properties 参数集 */ protected void setProperties4Query(Query query, Map<String, Object> properties) { for (Map.Entry<String, Object> entry : properties.entrySet()) { Object value = entry.getValue(); if ( !QueryCondition.isValueNullOrEmpty(value) ) { query.setParameter( entry.getKey(), value ); } } } /** * <p> * 获取总记录数 * </p> * @param sumQl 统计QL语句 * @param properties 参数集 * @return Integer 总记录数 */ protected Integer getTotalRows(String ql, Map<String, Object> properties) { // 生成对应的总记录数统计QL语句 int fromIndex = ql.toLowerCase().indexOf("from "); int toIndex = ql.toLowerCase().indexOf(" order by "); if(toIndex <= 0) { toIndex = ql.length(); } String sumHql = "select count(*) " + ql.substring(fromIndex, toIndex); Query query = this.createQuery(sumHql); setProperties4Query(query, properties); return EasyUtils.convertObject2Integer(query.getSingleResult()); } /** * <p> * 通过QL语句创建对应的Query对象 * </p> * @param ql 查询HQL/SQL语句 * @return Query对象 */ protected abstract Query createQuery(String ql); }