基于Mybatis的通用分页查询实现

     写在前面: 这套数据结构在spring+hibernate的框架上已经成熟运行多时,可直接将web前端的table查询插件生成的查询条件通过组件自动转换为CommonReqInqBean实例,然后调用HibernateGenericDao.pagedQuery完成分页查询,生成Page对象,然后将Page对象赋值给TableResponseBean的result属性。

  此文说明如何将此机制迁移至用Mybatis实现。

       首先,我们需要将通用的动态WHERE和动态ORDER子句提取出来,放在CommonMapper里面,以便被调用, 那么xml和java的代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.freestyle.common.db.mybatis.CommonMapper">  
  <sql id="inqOrder">
  	${orderLimit1}
  </sql>
  <sql id="inqWhere">
  	<where>
    	<foreach item="value" index="key" collection="conditions.entrySet()" separator=" and ">
    		<choose>
    			<when test="value.compare.toLowerCase() == 'between'">
    				${key} ${value.compare} #{value.vFrom} and #{value.vTo}		
    			</when>
    			<when test="value.compare.toLowerCase() == 'like'">
    				${key} ${value.compare} '%${value.vFrom}%'		
    			</when>
    			<when test="value.compare.toLowerCase() == 'in'">
    				${key} =
    				<foreach item="item" collection="value.toList()" open="any(array["  separator=","  close="])">
    					#{item}
    				</foreach>
    			</when>
    			<otherwise>
    			     ${key} ${value.compare} #{value.vFrom}
    			</otherwise>
    		</choose>    		
    	</foreach>	
    </where>    
     
  </sql>
  <select id="getTableRecordTotal" resultType="long">
  		select count(*) as cc from ${extObj} 
  		<include refid="inqWhere" />
  </select>
</mapper>

上面这个是xml mapper, 需要说明一下的是getTableRecordTotal用到的参数extObj是CommonReqInqBean的一个属性,这时候用来储存tablename,在调用getTableRecordTotal会将tablename赋值给extObj。

package com.freestyle.common.db.mybatis;

import com.freestyle.common.protocols.CommonReqInqBean;

public interface CommonMapper {
	/*@Select("select count(*) as cc from ${tablename} ")*/	
	public long getTableRecordTotal(CommonReqInqBean pvInq); 
}

CommonMapper.java则相对简单,只提供了一个获取Table记录数的接口功能.

好了,再看看CommonReqInqBean.java这个查询参数的数据结构和查询结果TableResponseBean.java的数据结构:

package com.freestyle.common.protocols;


import com.freestyle.common.utils.Util;

public class AjaxReqInqBean {
	public int pagenum=1;
	public int pagesize=10;
	public int caltotal=0;
	//public int groupscount;
	public String sortdatafield;
	public String sortorder;
	public String sortByColumn="0";
	public String defaultsortdatafield;
	//public boolean inited
	public boolean sortByColCell;
	public String sortByColVal="";
	public Object extObj;

	// public String sortorder; //asc ,desc

	public String genOrderLimit(){		
		String w_sortfield=Util.fillNullStr(sortdatafield);
		if (w_sortfield.equals("")&&defaultsortdatafield!=null){
			w_sortfield=defaultsortdatafield;
		}
		if (sortorder==null||sortorder.equals("")){
			sortorder="asc";
		}
		if (sqlValidate(w_sortfield)||sqlValidate(sortorder)){
			return "";
		}
		return (w_sortfield.equals("")?" " : " order by "+w_sortfield+(sortorder.equals("")?"":" "+sortorder))+" limit "+
	String.valueOf(pagesize)+" offset "+String.valueOf((pagenum * pagesize));
	}
	//效验  
    protected static boolean sqlValidate(String str) {  
        str = str.toLowerCase();//统一转为小写  
        String badStr = "'|and|exec|execute|insert|select|delete|update|count|drop|*|%|chr|mid|master|truncate|" +  
                "char|declare|sitename|net user|xp_cmdshell|;|or|-|+|,|like'|and|exec|execute|insert|create|drop|" +  
                "table|from|grant|use|group_concat|column_name|" +  
                "information_schema.columns|table_schema|union|where|select|delete|update|order|by|count|*|" +  
                "chr|mid|master|truncate|char|declare|or|;|-|--|+|,|like|//|/|%|#";//过滤掉的sql关键字,可以手动添加  
        String[] badStrs = badStr.split("\\|");  
        for (int i = 0; i < badStrs.length; i++) {  
            if (str.indexOf(badStrs[i]) >= 0) {  
                return true;  
            }  
        }  
        return false;  
    }  
    public String getOrderLimit1(){
    	return genOrderLimit1();
    }
	public String genOrderLimit1(){
		String w_sortfield=Util.fillNullStr(sortdatafield);
		if (w_sortfield.equals("")&&defaultsortdatafield!=null){
			w_sortfield=defaultsortdatafield;
		}
		if (sortorder==null||sortorder.equals("")){
			sortorder="asc";
		}
		if (sqlValidate(w_sortfield)||sqlValidate(sortorder)){
			return "";
		}
		return (w_sortfield.equals("")?" " : " order by "+w_sortfield+(sortorder.equals("")?"":" "+sortorder)
				)+" limit "+
	String.valueOf(pagesize)+" offset "+String.valueOf(((pagenum-1) * pagesize));
	}
	public String genOrder(){
		String w_sortfield=Util.fillNullStr(sortdatafield);
		if (w_sortfield.equals("")&&defaultsortdatafield!=null){
			w_sortfield=defaultsortdatafield;
		}
		if (w_sortfield.equals("")) return "";
		if (sortorder==null||sortorder.equals("")){
			sortorder="asc";
		}
		String[] lvT=w_sortfield.split(",");
		lvT[0]=lvT[0] +" "+sortorder;
		return "ORDER BY "+Util.toString(",", lvT);	}
	/***返回不带order by **/
	public String genOrder1(){
		String w_sortfield=Util.fillNullStr(sortdatafield);
		if (w_sortfield.equals("")&&defaultsortdatafield!=null){
			w_sortfield=defaultsortdatafield;
		}
		if (w_sortfield.equals("")) return "";
		if (sortorder==null||sortorder.equals("")){
			sortorder="asc";
		}
		String[] lvT=w_sortfield.split(",");
		lvT[0]=lvT[0] +" "+sortorder;
		return Util.toString(",", lvT);
	}	
}
package com.freestyle.common.protocols;


import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.time.DateUtils;

import com.fasterxml.jackson.core.type.TypeReference;
//import com.freestyle.common.spring.ContextHolder;
import com.freestyle.common.utils.JsonUtils;
//import com.freestyle.common.utils.Util;
import com.freestyle.common.utils.Util;

public class CommonReqInqBean extends AjaxReqInqBean {
	public static class ReqObj {
		public String compare;
		public String label;
		public String vFrom;
		public String vTo;
		public String[] toList(){
			return vFrom.split(",");
		}

		public String getCompare() {
			return compare;
		}

		public String getvFrom() {
			return vFrom;
		}

		public String getvTo() {
			return vTo;
		}
		public String toString(){
			String lvCompare=(compare==null?"=":compare);
			if (lvCompare.equals("between")){
				return lvCompare+" \""+vFrom+"\" and \""+vTo+"\"";
			}
			else{
				return lvCompare+" \""+vFrom+"\"";
			}
		}
	}
	public static void updateSortDataField(CommonReqInqBean pvInq,List<String> pvFields){
		if (pvInq.sortdatafield==null||pvInq.sortdatafield.equals("")){
			pvInq.sortdatafield=pvFields.get(Integer.valueOf(pvInq.sortByColumn));
		}		
	}
	public String toString() {
		return JsonUtils.jsonFromObject(this);
	}

	/***
	 * 用于显示下载Excel格式文档的底部查询条件集合显示
	 * 
	 * @return
	 */
	public String toShowExcelCriteria() {
		if (conditions == null)
			return "";
		StringBuilder lvSb = new StringBuilder();
		for (String lvKey : conditions.keySet()) {
			ReqObj lvReq = conditions.get(lvKey);
			if (lvReq.label == null)
				continue;
			lvSb.append(lvReq.label + ": " + lvReq.vFrom
					+ (lvReq.compare.equals("Between")
							? " To "
									+ lvReq.vTo
							: "")
					+ "<br/>\n");
		}
		return lvSb.toString();
	}

	public HashMap<String, ReqObj> conditions; // 条件组合

	public CommonReqInqBean() {
		conditions = new HashMap<String, ReqObj>();
	}

	public static CommonReqInqBean getReqBean(HttpServletRequest pvRequest) throws Exception {
		HashMap<String, TypeReference> lvFieldC = new HashMap<String, TypeReference>();
		lvFieldC.put("conditions", new TypeReference<HashMap<String, ReqObj>>() {
		});
		CommonReqInqBean p_req =HttpBeanUtil.beanFromUrlRequestByJsonV1(CommonReqInqBean.class, new TypeReference<CommonReqInqBean>() {
		}, pvRequest, null, lvFieldC);
		if (p_req.conditions!=null){
			for (Entry<String,ReqObj> item:p_req.conditions.entrySet()){
				String lvsKey=item.getKey();
				if (sqlValidate(lvsKey)){
					throw new Exception("Invalid Key name:"+lvsKey+", include invalid word.");
				}
			}
		}
		return p_req;
	}

	/***
	 * 將輸入的關鍵字(多個的話用回車或“,”分隔)轉換成Postgresql的ANY關鍵字
	 * 
	 * @param pvKeywords
	 * @return
	 */
	public static String keyWordsToAnyFormat(String pvKeywords) {
		pvKeywords = Util.fillNullStr(pvKeywords).trim().toUpperCase();
		if (pvKeywords.equals(""))
			return "";
		String[] lvItems = pvKeywords.replace("\n", ",").split(",");
		StringBuilder lvSb = new StringBuilder();
		int lvInc = 0;
		for (String item : lvItems) {
			if (item.trim().equals(""))
				continue;
			lvInc++;
			lvSb.append(String.format(",'%s'", item.trim()));
		}
		if (lvSb.length() > 1) {
			lvSb.delete(0, 1);
		} else {
			return "''";
		}
		if (lvInc == 1) {
			return lvSb.toString().trim();
		} else {
			return " ANY(array[" + lvSb.toString() + "]) ";
		}
	}

	public static class DateBetweenBean {
		public Date date1 = null;
		public Date date2 = null;
		public String compare = "=";
	}

	/***
	 * 从查询条件里面解析出日期范围
	 * @throws Exception 
	 */
	public static DateBetweenBean getDateFromReqObj(ReqObj pvKey) throws Exception {
		DateBetweenBean lvRet = new DateBetweenBean();
		lvRet.compare = pvKey.compare == null ? "=" : pvKey.compare;
		int lvDays=-1;
		try{
			lvDays=Integer.parseInt(pvKey.vFrom);
		}
		catch (Exception e){			
		}
		if (lvDays>0){
			lvRet.date1 = DateUtils.addDays(Util.getCurrentDate(), -lvDays);
			lvRet.date2 = Util.getCurrentDate();
			lvRet.compare="between";
		}
		else{
			lvRet.date1=Util.deformatDatetime(pvKey.vFrom, Util.c_java_datefmt);
			if (!pvKey.vFrom.equals("")&&lvRet.date1==null){
				throw new Exception("convert error.");
			}
			pvKey.vTo=Util.fillNullStr(pvKey.vTo);
			lvRet.date2=pvKey.vTo.equals("")? null:Util.deformatDatetime(pvKey.vTo, Util.c_java_datefmt);
			if (lvRet.date2==null && pvKey.compare.equals("between")){
				  lvRet.compare="=";
			}
			else if (lvRet.date2!=null){
				lvRet.compare="between";
			}
			if (!pvKey.vTo.equals("")&&lvRet.date2==null){
				throw new Exception("convert error.");
			}
		}
		return lvRet;
	}
	public static String valuesToArray(String pvVal){
		String lvRet="array['"+Util.toString(pvVal.split(","),"' , '")+"']";
		return lvRet;
	}
	public static String genReqClauseWithValue(String pvFieldName, ReqObj pvReqObj) {
		if (pvReqObj == null)
			return null;
		String lvV1 = pvReqObj.vFrom.trim();
		String lvV2 = pvReqObj.vTo == lvV1 ||pvReqObj.vTo ==null? null : pvReqObj.vTo.trim();
		if (pvReqObj.compare == null || pvReqObj.compare.equals("=")) {
			return String.format(" %s='%s' ", pvFieldName, lvV1);
		} else if (pvReqObj.compare.equals(">=")) {
			return String.format(" %s>='%s' ", pvFieldName, lvV1);
		} else if (pvReqObj.compare.equals("<=")) {
			return String.format(" %s<='%s' ", pvFieldName, lvV1);
		} else if (pvReqObj.compare.equals("<")) {
			return String.format(" %s<'%s' ", pvFieldName, lvV1);
		}
		else if (pvReqObj.compare.toLowerCase().equals("like")) {
			return String.format(" %s like '%s' ", pvFieldName, "%" + lvV1 + "%");
		} else if (pvReqObj.compare.equals(">")) {
			return String.format(" %s>'%s' ", pvFieldName, lvV1);
		} else if (pvReqObj.compare.toLowerCase().equals("between")) {
			return String.format(" %s between '%s' and '%s' ", pvFieldName, lvV1, lvV2);
		}
		else if (pvReqObj.compare.toLowerCase().equals("in")) {
			String lvValues=CommonReqInqBean.keyWordsToAnyFormat(pvReqObj.vFrom);
			return String.format(" %s=%s",pvFieldName,lvValues);
		}
		else if (pvReqObj.compare.toLowerCase().equals("includes")) {
			String lvValues=valuesToArray(pvReqObj.vFrom);
			return String.format(" %s && %s",pvFieldName,lvValues);
		}
		return null;
	}
	/*****
	 * 根据条件对象pvReqObj生成 SQL条件语句
	 * @param pvReqObj 比较符包括: >=,=,<=,>,<,between, in , includes ,其中,若为in ,则生成 fieldname=ANY(array[val1,val2,val3])格式<br/>
	 * 若为includes,则生成 fieldname && array[val1,val2,val3] ,表示是否有重叠,一般情况下fieldname这里亦需要是数组类型
	 */
	public static String genReqClause(String pvFieldName, ReqObj pvReqObj) {
		if (pvReqObj == null)
			return null;
		//String lvV1 = pvReqObj.vFrom.trim();
		//String lvV2 = pvReqObj.vTo == null ? null : pvReqObj.vTo.trim();
		if (pvReqObj.compare == null || pvReqObj.compare.equals("=")) {
			return String.format(" %s=:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals(">=")) {
			return String.format(" %s>=:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals("<=")) {
			return String.format(" %s<=:%s ", pvFieldName, pvFieldName);
		} 
		else if (pvReqObj.compare.equals("like")) {
			return String.format(" %s like :%s ", pvFieldName, pvFieldName);	
		}
		else if (pvReqObj.compare.equals("<")) {
			return String.format(" %s<:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals(">")) {
			return String.format(" %s>:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals("between")) {
			return String.format(" %s between :%s_1 and :%s_2 ", pvFieldName, pvFieldName, pvFieldName);
		}
		else if (pvReqObj.compare.equals("in")) {
			String lvValues=CommonReqInqBean.keyWordsToAnyFormat(pvReqObj.vFrom);
			return String.format(" %s=%s",pvFieldName,lvValues);
		}
		else if (pvReqObj.compare.equals("includes")) {
			String lvValues=valuesToArray(pvReqObj.vFrom);
			return String.format(" %s && %s",pvFieldName,lvValues);
		}
		return null;
	}
	public static String genReqClauseByDate(String pvFieldName, DateBetweenBean pvReqObj) {
		if (pvReqObj == null)
			return null;
		//String lvV1 = pvReqObj.vFrom.trim();
		//String lvV2 = pvReqObj.vTo == null ? null : pvReqObj.vTo.trim();
		if (pvReqObj.compare == null || pvReqObj.compare.equals("=")) {
			return String.format(" %s=:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals(">=")) {
			return String.format(" %s>=:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals("<=")) {
			return String.format(" %s<=:%s ", pvFieldName, pvFieldName);
		} 
		else if (pvReqObj.compare.equals("like")) {
			return String.format(" %s like :%s ", pvFieldName, pvFieldName);	
		}
		else if (pvReqObj.compare.equals("<")) {
			return String.format(" %s<:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals(">")) {
			return String.format(" %s>:%s ", pvFieldName, pvFieldName);
		} else if (pvReqObj.compare.equals("between")) {
			return String.format(" %s between :%s_1 and :%s_2 ", pvFieldName, pvFieldName, pvFieldName);
		}
		return null;
	}
}
package com.freestyle.common.protocols;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("serial")
public class Page implements Serializable {
    private static int DEFAULT_PAGE_SIZE = 20;
    private int pageSize = DEFAULT_PAGE_SIZE; // 每页的记录数
    private long start; // 当前页第一条数据在List中的位置,从0开始
    private Object rows; // 当前页中存放的记录,类型一般为List
    //private long currentPage;
    public String[] cols; //列标题
    private String sortorder=null;//"asc";
    private Integer sortByColumn=null;//"asc";
    public Integer getSortByColumn() {
		return sortByColumn;
	}
	public void setSortByColumn(Integer sortByColumn) {
		this.sortByColumn = sortByColumn;
	}
	public String getSortorder() {
		return sortorder;
	}
	public void setSortInfo(CommonReqInqBean pvInq,List<String> pvFields){
		setSortorder(pvInq.sortorder); //将sortorder 返回给前端!
		if (pvInq.sortdatafield==null||pvInq.sortdatafield.equals("")){
			setSortByColumn(null);
		}
		else{
			setSortByColumn(Integer.valueOf(pvFields.indexOf(pvInq.sortdatafield.split(",")[0])));
		}
	}
	public void setSortorder(String sortorder) {
		this.sortorder = sortorder;
	}
	//private Map<String,String> fieldMapping=null; // <字段名, 属性名>
    /*
    public Map<String, String> getFieldMapping() {
		return fieldMapping;
	}*/
	/*public void setFieldMapping(Map<String, String> fieldMapping) {
		this.fieldMapping = fieldMapping;
	}*/
	/*public long getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(long currentPage) {
		this.currentPage = currentPage;
	}*/
	private long totalRecords; // 总记录数
    /**
     * 构造方法,只构造空页.
     */
    @SuppressWarnings("unchecked")
    public Page() {
        this(0, 0, DEFAULT_PAGE_SIZE, new ArrayList());
    }
    /**
     * 默认构造方法.
     *
     * @param start  本页数据在数据库中的起始位置
     * @param totalSize 数据库中总记录条数
     * @param pageSize  本页容量
     * @param data    本页包含的数据
     */
    public Page(long start, long totalSize, int pageSize, Object data) {
        this.pageSize = pageSize;
        this.start = start;
        this.totalRecords = totalSize;
        this.rows = data;
        //this.sortorder="asc";
    }
    public Page(long start, long totalSize, int pageSize, Object data,String sortorder) {
        this.pageSize = pageSize;
        this.start = start;
        this.totalRecords = totalSize;
        this.rows = data;
        this.sortorder=sortorder;
    }
    /**
     * 默认构造方法.
     *
     * @param start  本页数据在数据库中的起始位置
     * @param totalSize 数据库中总记录条数
     * @param pageSize  本页容量
     * @param data    本页包含的数据
     * @param pvFieldMapping 数据字段名和属性名的映射
     * 
     */
    /*
    public Page(long start, long totalSize, int pageSize, Object data,Map<String,String> pvFieldMapping) {
        this.pageSize = pageSize;
        this.start = start;
        this.totalRecords = totalSize;
        this.rows = data;
        this.fieldMapping=pvFieldMapping;
    }*/
    
    /**
     * 取总记录数.
     */
    public long getTotalRecords() {
        return this.totalRecords;
    }
    /**
     * 取总页数.
     */
    public long getTotalPageCount() {
        if (totalRecords % pageSize == 0)
            return totalRecords / pageSize;
        else
            return totalRecords / pageSize + 1;
    }
    /**
     * 取每页数据容量.
     */
    public int getPageSize() {
        return pageSize;
    }
    /**
     * 取当前页中的记录.
     */
    public Object getRows() {
        return rows;
    }
    /**
     * 取当前页中的记录.
     */
    public void setRows(Object pvRows) {
        rows=pvRows;
    }
    /**
     * 取该页当前页码,页码从1开始.
     */
    
    public long getCurrentPage() {
        return start / pageSize + 1;
    }
    public void setCurrentPage(long pvPage){
    	start=(pvPage-1) * pageSize;
    }
    /**
     * 该页是否有下一页.
     */
    public boolean hasNextPage() {
        return this.getCurrentPage() < this.getTotalPageCount() - 1;
    }
    /**
     * 该页是否有上一页.
     */
    public boolean hasPreviousPage() {
        return this.getCurrentPage() > 1;
    }
    public void setCustPageSize(int pageSize){
    	this.pageSize=pageSize;
    }
    /**
     * 获取任一页第一条数据在数据集的位置,每页条数使用默认值.
     *
     * @see #getStartOfPage(int,int)
     */
    protected static int getStartOfPage(int pageNo) {
        return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE);
    }
    /**
     * 获取任一页第一条数据在数据集的位置.
     *
     * @param pageNo   从1开始的页号
     * @param pageSize 每页记录条数
     * @return 该页第一条数据
     */
    public static int getStartOfPage(int pageNo, int pageSize) {
        return (pageNo - 1) * pageSize;
    }
}

package com.freestyle.common.protocols;

import com.freestyle.common.hibernate.dao.support.Page;

public class TableResponseBean extends JSONData {
	public Page  result;
	public TableResponseBean(){
		errCode=0;
		errMsg="";
		result=null;//new TableResult();
	}
	
}

那现在开始写通用的分布查询工具类MybatisPager, 它提供了两个pageQuery,区别在于一个是传mybatis statement,一个是传record list对象进去再包装出TableResponseBean.

package com.freestyle.common.db.mybatis;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.freestyle.common.db.mybatis.MybatisUtils.SqlSessionInterface;
import com.freestyle.common.protocols.CommonReqInqBean;
import com.freestyle.common.protocols.Page;
import com.freestyle.common.protocols.TableResponseBean;

/***
 * Mybatis分页查询工具
 * 
 * @author dgmislrh
 *
 */
public class MybatisPager {
	public static  TableResponseBean pageQuery(String pvsStatement, CommonReqInqBean pvInq, String pvsMainTable) {
		TableResponseBean lvRet = 
		MybatisUtils.openSession(new SqlSessionInterface<TableResponseBean>() {
			@Override
			public TableResponseBean onExecute(SqlSession pvSqlSess) {
				TableResponseBean lvRet=null;
				try {
					List<Map<String, Object>> lvList = pvSqlSess.selectList(pvsStatement, pvInq);
					lvRet=pageQuery(lvList, pvInq, pvsMainTable,pvSqlSess);
				} catch (Exception e) {
					e.printStackTrace();
					lvRet.errCode = -1;
					lvRet.errMsg = e.getMessage();
					pvSqlSess.rollback();
				}
				return lvRet;
			}
		});
		return lvRet;
	}

	public static TableResponseBean pageQuery(Object pvRows, CommonReqInqBean pvInq, String pvsMainTable,
			SqlSession pvSqlSess) {
		TableResponseBean lvRet = new TableResponseBean();
		try {
			int startIndex = Page.getStartOfPage(pvInq.pagenum, pvInq.pagesize);
			long lvCC = 0;
			Object lvSave = pvInq.extObj;
			pvInq.extObj = pvsMainTable;
			try {
				lvCC = pvSqlSess.getMapper(CommonMapper.class).getTableRecordTotal(pvInq);
			} finally {
				pvInq.extObj = lvSave;
			}
			Page lvPage = new Page(startIndex, lvCC, pvInq.pagesize, pvRows);
			lvRet.result = lvPage;
		} catch (Exception e) {
			e.printStackTrace();
			lvRet.errCode = -1;
			lvRet.errMsg = e.getMessage();


		}
		return lvRet;
	}

}


再看看mybatis-config.xml里面注册的mappers:
<mappers>
  	 <mapper resource="com/freestyle/common/db/mybatis/CommonMapper.xml" />  	 
  	 <mapper resource="com/freestyle/proxoolmybatisstudy/dao/TaUserMapper.xml" />
  	 <mapper resource="com/freestyle/proxoolmybatisstudy/dao/TdNotifyMapper.xml" />
   </mappers>


上面都是准备工作, 那么如何调用呢? 以TaUser为例增加分布查询功能,  那只需要增加selectPage接口:


在TaUserMapper.xml里面增加selectPage的功能(请注意有两个include分别引用通用查询子句),对应的接口function: List<Map<String,Object>> selectPage(CommonReqInqBean pvInq);

<select id="selectPage" parameterType="com.freestyle.common.protocols.CommonReqInqBean" resultType="java.util.HashMap">
  	select fa_login, fa_name, fa_status, fa_type, fa_create_by, fa_create_dt, fa_update_by, 
      fa_update_dt, fa_email, fa_passwd, fa_remark, fa_staff_id, fa_last_notify
    from ta_user 
    <include refid="com.freestyle.common.db.mybatis.CommonMapper.inqWhere" />
    <include refid="com.freestyle.common.db.mybatis.CommonMapper.inqOrder" />            
  </select>

好, 现在开一个Junit测试(是不是觉得CommonReqInqBean蛮复杂的, 其实直接应用起来就一句getReqBean就可以将前端的数据直接转为java实例):

@Test
	public void testSelectPage(){
		CommonReqInqBean pvInq=new CommonReqInqBean();
		//设置排序&分布
		pvInq.sortdatafield="fa_login";
		pvInq.sortorder="asc";
		pvInq.pagenum=1;
		pvInq.pagesize=10;
		
		ReqObj lvReqLogin=new ReqObj();
		lvReqLogin.label="Login ID";
		lvReqLogin.compare="Between";
		lvReqLogin.vFrom="admin";
		lvReqLogin.vTo="cz";
		//增加一个fa_login的查询条件(fa_login要在admin与cz之间)
		pvInq.conditions.put("fa_login", lvReqLogin);		
		SqlSession lvSess=MybatisUtils.getSession();
		try
		{		
			//更改fa_login的查询条件为 in ('admin','hufei')
			lvReqLogin.compare="in";
			lvReqLogin.vFrom="admin,hufei";
			ReqObj lvReqStatus=new ReqObj();
			lvReqStatus.compare="=";
			lvReqStatus.vFrom="A";
			lvReqStatus.label="Status";
			//再增加一个查询条件为fa_status='A'的 
			pvInq.conditions.put("fa_status", lvReqStatus);
			TaUserMapper lvUserMapper=lvSess.getMapper(TaUserMapper.class);
			TableResponseBean lvRet=MybatisPager.pageQuery(lvUserMapper.selectPage(pvInq), pvInq, "ta_user",lvSess);
			System.out.println(pvInq.toShowExcelCriteria());
			
			try {
				System.out.println("查询条件数据结构:"+JsonUtils.jsonPrettyFromObject(pvInq));
				System.out.println("结果数据结构:"+JsonUtils.jsonPrettyFromObject(lvRet));
			} catch (JsonProcessingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		finally{
			MybatisUtils.closeSession(lvSess);
		}			
		
	}

测试结果:

==>  Preparing: select fa_login, fa_name, fa_status, fa_type, fa_create_by, fa_create_dt, fa_update_by, fa_update_dt, fa_email, fa_passwd, fa_remark, fa_staff_id, fa_last_notify from ta_user WHERE fa_status = ? and fa_login = any(array[ ? , ? ]) order by fa_login asc limit 10 offset 0 
==> Parameters: A(String), admin(String), hufei(String)
<==    Columns: fa_login, fa_name, fa_status, fa_type, fa_create_by, fa_create_dt, fa_update_by, fa_update_dt, fa_email, fa_passwd, fa_remark, fa_staff_id, fa_last_notify
<==        Row: admin, 管理员, A, A, test1, 2016-09-19 15:24:40.594, supuser1, 2016-10-14 15:47:35.312, , d1841df9a9ead353f339dd239a1b4676, , , 9711
<==        Row: hufei, 胡飞, A, N, 00001, 2017-03-21 09:39:43.903, 00001, 2017-03-22 12:06:36.768, , ab257d341f5d5afe96bc489a2534b7d8, , , null
<==      Total: 2
==>  Preparing: select count(*) as cc from ta_user WHERE fa_status = ? and fa_login = any(array[ ? , ? ]) 
==> Parameters: A(String), admin(String), hufei(String)
<==    Columns: cc
<==        Row: 2
<==      Total: 1
Status:&nbsp;A<br/>
Login ID:&nbsp;admin,hufei<br/>


查询条件数据结构:{
  "pagenum" : 1,
  "pagesize" : 10,
  "caltotal" : 0,
  "sortdatafield" : "fa_login",
  "sortorder" : "asc",
  "sortByColumn" : "0",
  "defaultsortdatafield" : null,
  "sortByColCell" : false,
  "sortByColVal" : "",
  "extObj" : null,
  "conditions" : {
    "fa_status" : {
      "compare" : "=",
      "label" : "Status",
      "vFrom" : "A",
      "vTo" : null
    },
    "fa_login" : {
      "compare" : "in",
      "label" : "Login ID",
      "vFrom" : "admin,hufei",
      "vTo" : "cz"
    }
  },
  "orderLimit1" : " order by fa_login asc limit 10 offset 0"
}
结果数据结构:{
  "errCode" : 0,
  "errMsg" : "",
  "errRef" : "",
  "result" : {
    "pageSize" : 10,
    "rows" : [ {
      "fa_name" : "管理员",
      "fa_update_dt" : 1476431255312,
      "fa_status" : "A",
      "fa_update_by" : "supuser1",
      "fa_email" : "",
      "fa_type" : "A",
      "fa_create_by" : "test1",
      "fa_login" : "admin",
      "fa_passwd" : "d1841df9a9ead353f339dd239a1b4676",
      "fa_last_notify" : 9711,
      "fa_remark" : "",
      "fa_create_dt" : 1474269880594,
      "fa_staff_id" : ""
    }, {
      "fa_name" : "胡飞",
      "fa_update_dt" : 1490155596768,
      "fa_status" : "A",
      "fa_login" : "hufei",
      "fa_passwd" : "ab257d341f5d5afe96bc489a2534b7d8",
      "fa_remark" : "",
      "fa_create_dt" : 1490060383903,
      "fa_update_by" : "00001",
      "fa_email" : "",
      "fa_staff_id" : "",
      "fa_type" : "N",
      "fa_create_by" : "00001"
    } ],
    "cols" : null,
    "sortorder" : null,
    "sortByColumn" : null,
    "totalRecords" : 2,
    "currentPage" : 1,
    "totalPageCount" : 1
  }
}


猜你喜欢

转载自blog.csdn.net/rocklee/article/details/80525545