写在前面: 这套数据结构在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; } }
<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: A<br/> Login ID: 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 } }