一、前言
基于PostgreSQL数据库,通过定义PostgreSqlPaginatedEnhance实现类及AbstractPaginatedEnhance抽象类实现常用分页查询调用方法,详情参见代码示例。
二、代码示例
1. PostgreSqlPaginatedEnhance类
import java.util.ArrayList;@b@import java.util.List;@b@import java.util.Map; @b@import net.sf.cglib.proxy.Enhancer; @b@import org.springframework.stereotype.Component; @b@import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping;@b@@b@@Component("postgreSqlPaginatedEnhance")@b@@SuppressWarnings({ "rawtypes", "unchecked" })@b@public class PostgreSqlPaginatedEnhance extends AbstractPaginatedEnhance {@b@@b@ public String getCountSql(String sql) {@b@ return "select count(*) from (" + sql + ") as st";@b@ }@b@@b@ @b@ public Map pagedMap(Map map, int skip, int pageSize) {@b@ int start = skip;@b@ int end = pageSize;@b@ map.put(START_PROP, Integer.valueOf(start));@b@ map.put(END_PROP, Integer.valueOf(end));@b@ return map;@b@ }@b@@b@ public Object pagedObject(Object value, int skip, int pageSize) {@b@ // rownum 从1开始@b@ int start = skip;@b@ int end = pageSize;@b@@b@ // java bean@b@ Enhancer enhancer = new Enhancer();@b@ enhancer.setCallback(new PagedHandler(value, end, start)); // 问题@b@ enhancer.setSuperclass(value.getClass());@b@ enhancer.setInterfaces(ADD_ON);@b@ return enhancer.create();@b@ }@b@@b@ public String getQuerySql(String sql) { @b@ String s = new StringBuffer(sql.length() + 10).append(sql).append(" limit ? OFFSET ? ").toString();@b@ return s;@b@}@b@@b@ @Override@b@ protected List sortParameterMap(List mappingList) {@b@@b@ if (mappingList == null || mappingList.size() < 2) return mappingList;@b@@b@ ParameterMapping t = (ParameterMapping) mappingList.get(0);@b@@b@ if (t.getPropertyName().equals(START_PROP)) return mappingList;@b@@b@ // List newMappingList = new ArrayList();@b@@b@ ParameterMapping startPm = null;@b@ ParameterMapping endPm = null;@b@@b@ for (int i = 0, n = mappingList.size(); i < n && i < 2; i++) {@b@ ParameterMapping pm = (ParameterMapping) mappingList.get(n - 1 - i);@b@ if (pm.getPropertyName().equals(START_PROP)) {@b@ startPm = pm;@b@ }@b@@b@ if (pm.getPropertyName().equals(END_PROP)) {@b@ endPm = pm;@b@ }@b@ }@b@@b@ // 重新对参数进行排序@b@ List newMappingList = getResultMapping(mappingList, startPm, endPm);@b@@b@ return newMappingList;@b@ }@b@@b@ private List getResultMapping(List mappingList, ParameterMapping startPm, ParameterMapping endPm) {@b@ List newMappingList = new ArrayList();@b@ if (startPm != null && endPm != null) {@b@ for (int i = 0, n = mappingList.size(); i < n - 2; i++) {@b@ newMappingList.add(mappingList.get(i));@b@ }@b@ newMappingList.add(startPm);@b@ newMappingList.add(endPm);@b@ } else { // 没有分页关键字 star , end@b@ newMappingList = mappingList;@b@ }@b@ return newMappingList;@b@ }@b@}
2. AbstractPaginatedEnhance类
import java.lang.reflect.Method;@b@import java.sql.SQLException;@b@import java.util.ArrayList;@b@import java.util.Arrays;@b@import java.util.HashMap;@b@import java.util.Iterator;@b@import java.util.List;@b@import java.util.Map;@b@@b@import net.sf.cglib.proxy.Enhancer;@b@@b@import com.ibatis.sqlmap.client.SqlMapClient;@b@import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;@b@import com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMap;@b@import com.ibatis.sqlmap.engine.mapping.parameter.BasicParameterMapping;@b@import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;@b@import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping;@b@import com.ibatis.sqlmap.engine.mapping.result.AutoResultMap;@b@import com.ibatis.sqlmap.engine.mapping.result.BasicResultMap;@b@import com.ibatis.sqlmap.engine.mapping.result.ResultMap;@b@import com.ibatis.sqlmap.engine.mapping.sql.Sql;@b@import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;@b@import com.ibatis.sqlmap.engine.mapping.statement.SelectStatement;@b@import com.ibatis.sqlmap.engine.scope.RequestScope;@b@import com.xwood.soofa.service.persistence.dao.ibatis.DelegateSql;@b@import com.xwood.soofa.service.persistence.dao.ibatis.SqlMapClientTemplate;@b@import com.xwood.soofa.service.persistence.dao.ibatis.enhance.IbatisPlugin;@b@import com.xwood.soofa.service.persistence.dao.ibatis.enhance.SqlMapEnhance;@b@@b@abstract public class AbstractPaginatedEnhance implements SqlMapEnhance {@b@@b@ protected static final String START_GETTER = "getStartPosition_";@b@@b@ protected static final String START_PROP = "startPosition_";@b@@b@ protected static final String END_GETTER = "getEndPosition_";@b@@b@ protected static final String END_PROP = "endPosition_";@b@@b@ // 使用一个特殊的key传输原始类型@b@ private static final Object INLINE_VALUE_KEY = new Object();@b@@b@ public class CountSql extends DelegateSql {@b@ public CountSql(Sql sql) {@b@ super(sql);@b@ }@b@@b@ @Override@b@ protected String decorateSql(String sql) {@b@ return getCountSql(sql);@b@ }@b@ }@b@@b@ public class QuerySql extends DelegateSql {@b@ public QuerySql(Sql sql) {@b@ super(sql);@b@ }@b@@b@ /**@b@ * 动态查询参数Mapping需要每次执行的时候构建,同时调整输入参数@b@ */@b@ @Override@b@ public ParameterMap getParameterMap(RequestScope request,@b@ Object parameter) {@b@@b@ // 根据实际参数情况来处理是否需要调整@b@ BasicParameterMap map = (BasicParameterMap) super.getParameterMap(@b@ request, parameter);@b@ ParameterMapping[] mappings = map.getParameterMappings();@b@ if (needRemapping(mappings)) {@b@ List mappingList = getParameterMappingList(mappings,@b@ map.getDelegate(), request.getStatement());@b@@b@ map.setParameterMappingList(mappingList);@b@ mappings = map.getParameterMappings();@b@ mappingList = null;@b@ }@b@@b@ if (null != parameter) {@b@ if (parameter instanceof Map) {@b@ swapOutInlineValue(mappings[0].getPropertyName(),@b@ (Map) parameter);@b@ }@b@ }@b@@b@ /**@b@ * 根据不同数据库重新排列参数顺序@b@ */@b@ List mappingList1 = new ArrayList();@b@ mappingList1.addAll(Arrays.asList(mappings));@b@@b@ mappingList1 = sortParameterMap(mappingList1);@b@@b@ map.setParameterMappingList(mappingList1);@b@@b@ mappingList1 = null;@b@@b@ return map;@b@ }@b@@b@ private boolean needRemapping(ParameterMapping[] mappings) {@b@ if (mappings.length < 2) {@b@ return true;@b@ }@b@ if (!((START_PROP).equals(mappings[mappings.length - 1]@b@ .getPropertyName()))) {@b@ return true;@b@ }@b@@b@ return false;@b@@b@ }@b@@b@ @Override@b@ protected String decorateSql(String sql) {@b@ String s = getQuerySql(sql);@b@@b@ return s;@b@ }@b@ }@b@@b@ /**@b@ * count sql语句,简单采用nest query方式@b@ * @b@ * @param sql@b@ * @return@b@ */@b@ abstract protected String getCountSql(String sql);@b@@b@ @b@ abstract protected String getQuerySql(String sql);@b@@b@ /**@b@ * <p>@b@ * ?根据数据库类型进行参数排序@b@ * </p>@b@ * @b@ * @param@b@ * @return@b@ * @throws@b@ * @see@b@ * @since %I%@b@ */@b@ abstract protected List sortParameterMap(List mappingList);@b@@b@ @b@ @b@ /**@b@ * 对需要分页的查询,重新创建两个statement: !count和!paged@b@ */@b@ @Override@b@ public void enhance(SqlMapClient sqlMapClient) throws Exception {@b@ SqlMapExecutorDelegate delegate = IbatisPlugin@b@ .getDelegate(sqlMapClient);@b@ for (Iterator it = queryStatements.iterator(); it.hasNext();) {@b@ String id = (String) it.next();@b@ MappedStatement statement = IbatisPlugin.getStatement(delegate@b@ .getMappedStatement(id));@b@ if (statement instanceof SelectStatement) {@b@ SelectStatement select = (SelectStatement) statement;@b@ String countId = getCountId(id);@b@ // 避免重复追加,同时,也提供了通过配置来覆盖默认实现的可能@b@ if (!IbatisPlugin.hasStatement(delegate, countId)) {@b@ // 创建count Statement@b@ SelectStatement count = new SelectStatement();@b@ count.setFetchSize(new Integer(1));@b@ count.setId(countId);@b@ count.setSql(new CountSql(select.getSql()));@b@ count.setParameterMap(select.getParameterMap());@b@ count.setParameterClass(select.getParameterClass());@b@ count.setSqlMapClient(select.getSqlMapClient());@b@ count.setResource("PafaHugePagedQuery!count:"@b@ + select.getResource());@b@ count.setResultMap(buildCountResultMap(delegate, count));@b@ count.setBaseCacheKey(delegate.hashCode());@b@ addMappedStatement(delegate, count);@b@ }@b@ String queryId = getQueryId(id);@b@ if (!IbatisPlugin.hasStatement(delegate, queryId)) {@b@ // 翻页查询Statement@b@ SelectStatement pagedQuery = new SelectStatement();@b@ // pagedQuery.setFetchSize(new Integer(1)); // prefer@b@ // pageSize@b@ pagedQuery.setSqlMapClient(select.getSqlMapClient());@b@ // 沿用原有ResultMap即可@b@ pagedQuery@b@ .setResultMap(buildPageResultMap(delegate, select));@b@ pagedQuery.setResource("PafaHugePagedQuery!Query:"@b@ + select.getResource());@b@ pagedQuery.setId(queryId);@b@ pagedQuery.setSql(new QuerySql(select.getSql()));@b@ // 调整参数类型@b@ Class targetType = getQueryParameterClass(delegate, select);@b@ pagedQuery.setParameterClass(targetType);@b@ ParameterMap oldMap = select.getParameterMap();@b@ if (null != oldMap) {@b@ // 调整参数Mapping@b@ BasicParameterMap newMap = new BasicParameterMap(@b@ delegate);@b@ newMap.setId(pagedQuery.getId() + "-autoParameterMap");@b@ newMap.setResource("PafaHugePagedQuery");@b@ newMap.setParameterClass(pagedQuery.getParameterClass());@b@ ParameterMapping[] mappings = oldMap@b@ .getParameterMappings();@b@ if (null == mappings) {@b@ // mappings中,null与 || 0 ==@b@ // mappings.length不同,后者表示没有参数输入@b@ // 动态SQL的ParameterMapping执行的时候才会被创建,参见@see QuerySql@b@ // throw new@b@ // Exception("动态SQL的ParameterMapping执行的时候才会被创建");@b@ } else {@b@ List mappingList = getParameterMappingList(@b@ mappings, delegate, select);@b@ newMap.setParameterMappingList(mappingList);@b@ }@b@ pagedQuery.setParameterMap(newMap);@b@ } else {@b@ // 动态SQL的参数ParameterMap或者ResultMap执行的时候才会被创建@b@ // throw new@b@ // Exception("动态SQL的参数ParameterMap或者ResultMap执行的时候才会被创建");@b@ // System.out.println("##############################" +@b@ // id + " No ParameterMap");@b@ }@b@ addMappedStatement(delegate, pagedQuery);@b@ }@b@ } else {@b@ // error@b@ throw new Exception("只能改进SelectStatement,ID=" + id + "类型是"@b@ + statement.getStatementType());@b@ }@b@ }@b@ }@b@@b@ private static final Object lock = new Object();@b@@b@ private void addMappedStatement(SqlMapExecutorDelegate delegate,@b@ SelectStatement pagedQuery) {@b@ synchronized (lock) {@b@ delegate.addMappedStatement(pagedQuery);@b@ }@b@ }@b@@b@ /**@b@ * 构建count后的返回类型,为了有更好的兼容,返回Long@b@ * @b@ * @param executorDelegate@b@ * @param statement@b@ * @return@b@ */@b@ private BasicResultMap buildCountResultMap(@b@ SqlMapExecutorDelegate executorDelegate, MappedStatement statement) {@b@ BasicResultMap resultMap;@b@ resultMap = new AutoResultMap(executorDelegate, false);@b@ resultMap.setId(statement.getId() + "-AutoResultMap");@b@ resultMap.setResultClass(Long.class);@b@ // resultMap.setXmlName(xmlResultName);@b@ // resultMap.setResource(statement.getResource());@b@ return resultMap;@b@ }@b@@b@ /**@b@ * <p>@b@ * ?为分页单独构造一个resultmap对象@b@ * </p>@b@ * @b@ * @param executorDelegate@b@ * @param statement@b@ * @param select@b@ * @return@b@ * @throws@b@ * @see@b@ * @since %I%@b@ */@b@ private ResultMap buildPageResultMap(@b@ SqlMapExecutorDelegate executorDelegate,@b@ SelectStatement selectStatement) {@b@ BasicResultMap resultMap;@b@ ResultMap rm = selectStatement.getResultMap();@b@ if (rm instanceof AutoResultMap) {// 如果参数是Map,需重新构建一个ResultMap@b@ resultMap = new AutoResultMap(executorDelegate, true);@b@ } else {// 如果参数是DTO@b@ resultMap = (BasicResultMap) selectStatement.getResultMap();@b@ }@b@ // resultMap = new AutoResultMap(executorDelegate, true);@b@ resultMap.setId(selectStatement.getId() + "-PageResultMap");@b@ resultMap.setResultClass(selectStatement.getResultMap()@b@ .getResultClass());@b@ return resultMap;@b@ }@b@@b@ /**@b@ * 需要优化翻页(以及count)的查询ID List@b@ */@b@ private List queryStatements = new ArrayList();@b@@b@ public List getQueryStatements() {@b@ return queryStatements;@b@ }@b@@b@ public void setQueryStatements(List queryStatements) {@b@ this.queryStatements = queryStatements;@b@ }@b@@b@ public Map pagedPrimitive(Object parameter, int skip, int pageSize) {@b@ HashMap params = new HashMap();@b@ // 使用一个特殊的key传输原始类型,传入@b@ params.put(INLINE_VALUE_KEY, parameter);@b@ return pagedMap(params, skip, pageSize);@b@ }@b@@b@ /**@b@ * 通过cglib来加强对象,从而能够获取startPosition_/endPosition_两个属性@b@ * @b@ * @param value@b@ * @param skip@b@ * @param pageSize@b@ * @return@b@ */@b@ abstract public Object pagedObject(Object value, int skip, int pageSize);@b@@b@ @b@@b@ abstract public Map pagedMap(Map map, int skip, int pageSize);@b@@b@ @b@@b@ /**@b@ * 获取加强后的对象类型@b@ * @b@ * @param type@b@ * @return@b@ */@b@ public static Class pagedClass(Class type) {@b@ Enhancer enhancer = new Enhancer();@b@ enhancer.setCallbackType(PagedHandler.class);@b@ enhancer.setSuperclass(type);@b@ enhancer.setInterfaces(ADD_ON);@b@ // enhancer.setClassLoader(loader);@b@ return enhancer.createClass();@b@ }@b@@b@ /**@b@ * 由于这个接口方法会被用于类的加强,因此必须为public@b@ */@b@ public static interface Paged {@b@ public int getStartPosition_();@b@@b@ public int getEndPosition_();@b@ }@b@@b@ public static Class[] ADD_ON = { Paged.class };@b@@b@ public static class PagedHandler implements@b@ net.sf.cglib.proxy.InvocationHandler {@b@ PagedHandler(Object value, int iStart, int iEnd) {@b@ this.oldBean = value;@b@ this.start = new Integer(iStart);@b@ this.end = new Integer(iEnd);@b@ }@b@@b@ @Override@b@ public Object invoke(Object proxy, Method method, Object[] args)@b@ throws Throwable {@b@ String name = method.getName();@b@ if (START_GETTER.equals(name)) {@b@ return start;@b@ }@b@ if (END_GETTER.equals(name)) {@b@ return end;@b@ }@b@ return method.invoke(oldBean, args);@b@ }@b@@b@ // 原始对象@b@ private final Object oldBean;@b@@b@ // 起始位置@b@ private final Integer start, end;@b@ }@b@@b@ /**@b@ * 提供工具方法,获取改进后的SQLMAP中,指定查询ID的count结果@b@ * @b@ * @param sqlMapClient@b@ * @param id@b@ * 原始查询的ID@b@ * @param parameter@b@ * 查询条件@b@ * @return 返回记录数(long)@b@ * @throws SQLException@b@ * 查询发生异常,或者该statement并没有加强时@b@ */@b@ public long count(SqlMapClientTemplate sqlMapClientTemplate, String id,@b@ Object parameter) throws SQLException {@b@ Object result = sqlMapClientTemplate.queryForObject(getCountId(id),@b@ parameter);@b@ if (null == result)@b@ return 0L;@b@ return ((Long) result).longValue();@b@ }@b@@b@ /**@b@ * 采用优化的方式,进行翻页查询@b@ * @b@ * @param sqlMapClient@b@ * @param id@b@ * 原始查询的ID@b@ * @param parameter@b@ * 查询条件@b@ * @param skip@b@ * 忽略记录的条数,必须 >= 0@b@ * @param pageSize@b@ * 查询的最大条数@b@ * @return 查询的结果@b@ * @throws SQLException@b@ */@b@ public List queryForList(SqlMapClientTemplate sqlMapClientTemplate,@b@ String id, Object parameter, int skip, int pageSize)@b@ throws SQLException {@b@ String queryId = getQueryId(id);@b@ Object newParameter = getQueryParameter(@b@ IbatisPlugin@b@ .getDelegate(sqlMapClientTemplate.getSqlMapClient()),@b@ queryId, parameter, skip, pageSize);@b@ List res = sqlMapClientTemplate.queryForList(queryId, newParameter);@b@ return res;@b@ }@b@@b@ /**@b@ * count对应statement ID@b@ * @b@ * @param id@b@ * @return@b@ */@b@ public static String getCountId(String id) {@b@ return "_pafacount~" + id;@b@ }@b@@b@ // -- 开始处理翻页综合查询的 -----------@b@ public static String getQueryId(String id) {@b@ return "_pafapage~" + id;@b@ }@b@@b@ /**@b@ * 一个内部协议,用于处理原始类型参数的传递:由于动态SQL开始的时候并不知道参数名。@b@ * 因此使用一个特殊的key传输原始类型,这里按参数名把参数置入Map,同时删除特殊的key@b@ * @b@ * @param parameterName@b@ * @param parameter@b@ */@b@ public static void swapOutInlineValue(String parameterName, Map parameter) {@b@ // 防止重复处理时覆盖@b@ if (!parameter.containsKey(INLINE_VALUE_KEY))@b@ return;@b@ // 不存在参数,防止错误覆盖@b@ if (END_PROP.equals(parameterName) || START_PROP.equals(parameterName)) {@b@ return;@b@ }@b@ // 先删除@b@ Object value = parameter.remove(INLINE_VALUE_KEY);@b@ parameter.put(parameterName, value);@b@ }@b@@b@ public static List getParameterMappingList(ParameterMapping[] mappings,@b@ SqlMapExecutorDelegate delegate, MappedStatement select) {@b@ List mappingList = new ArrayList();@b@ mappingList.addAll(Arrays.asList(mappings));@b@ // parameter需要添加两个参数@b@ // end在前start在后@b@ boolean exists = false;@b@ for (int i = 0, n = (mappings == null ? 0 : mappings.length); i < n@b@ && i < 2; i++) {@b@ ParameterMapping m = mappings[n - 1 - i];@b@ if (m.getPropertyName().equals(END_PROP)@b@ || m.getPropertyName().equals(START_PROP)) {@b@ exists = true;@b@ break;@b@ }@b@@b@ }@b@@b@ if (!exists) {@b@ mappingList.add(getIntParameterMapping(END_PROP, delegate, select));@b@ mappingList@b@ .add(getIntParameterMapping(START_PROP, delegate, select));@b@ }@b@ return mappingList;@b@ }@b@@b@ /**@b@ * 构建integer类型的ParameerMapping,用于处理输入参数@b@ * @b@ * @param name@b@ * @param delegate@b@ * @param statement@b@ * @return@b@ */@b@ public static ParameterMapping getIntParameterMapping(String name,@b@ SqlMapExecutorDelegate delegate, MappedStatement statement) {@b@ BasicParameterMapping start = new BasicParameterMapping();@b@ start.setJavaType(Integer.class);@b@ start.setPropertyName(name);@b@ start.setTypeHandler(delegate.getTypeHandlerFactory().getTypeHandler(@b@ Integer.class));@b@ return start;@b@ }@b@@b@ /**@b@ * 获取Statement中的ParameterClass,如果没有设置,尝试获取ParameterMap中的设置,没有则返回空@b@ * 但是注意:动态sql/默认自动识别都没有类别@b@ * @b@ * @param statement@b@ * @return@b@ */@b@ protected static Class getParameterType(MappedStatement statement) {@b@ Class oldType = statement.getParameterClass();@b@ if (null == oldType) {@b@ if (null != statement.getParameterMap()) {@b@ oldType = statement.getParameterMap().getParameterClass();@b@ }@b@ }@b@ return oldType;@b@ }@b@@b@ /**@b@ * 根据原有statement中的parameterClass的设置,设置新的查询的ParameterClass。包括很多场景@b@ * <ul>@b@ * <li><b>没有设置</b>:parameterClass或者parameterMap中都没有设置parameterClass,也不做设置,@b@ * 执行时解析实际用户传递的参数</li>@b@ * <li><b>原始类型</b>:包括string, date, 各种number等,返回null。从而让查询后面可以接受Map为参数</li>@b@ * <li><b>Map</b>:返回Map</li>@b@ * <li><b>List</b>:返回List</li>@b@ * <li><b>DOM</b>:返回DOM</li>@b@ * <li><b>JavaBean</b>:不属于以上任何类型,返回cglib加强后的类型,mixin了@see@b@ * Paged接口的方法,用于支持翻页的相关参数</li>@b@ * </ul>@b@ * @b@ * @param delegate@b@ * @param statement@b@ * @return@b@ */@b@ public static Class getQueryParameterClass(SqlMapExecutorDelegate delegate,@b@ MappedStatement statement) {@b@ Class oldType = getParameterType(statement);@b@ // 没有指定,默认情况,或者动态SQL@b@ if (null == oldType) {@b@ // return Map.class;@b@ return null;@b@ }@b@@b@ if (Map.class.isAssignableFrom(oldType)) {@b@ return oldType;@b@ }@b@@b@ if (IbatisPlugin.isPrimitive(delegate, oldType)) {@b@ return null;@b@ // return oldType;@b@ }@b@ // TODO DOM and List not support@b@ if (IbatisPlugin.isList(delegate, oldType)) {@b@ throw new RuntimeException("暂时不能支持List/Array/DOM参数");@b@ }@b@@b@ // javabean@b@ return (pagedClass(oldType));@b@ }@b@@b@ /**@b@ * 根据翻页查询的需要,重新组织参数,把skip与pageSize也嵌入参数中。返回的类型参见@b@ * {@link #getQueryParameterClass(SqlMapExecutorDelegate, MappedStatement)}@b@ * 的说明。 添加的内容都是追加翻页需要的两个参数。其中对于原始类型,转换为Map@b@ */@b@ public Object getQueryParameter(SqlMapExecutorDelegate delegate, String id,@b@ Object parameter, int skip, int pageSize) {@b@ if (null == parameter) {@b@ return pagedPrimitive(parameter, skip, pageSize);@b@ }@b@@b@ // 由于SQLMap中可以不定义parameterClass,只能根据实际类型参数类型来处理@b@ Class type = parameter.getClass();@b@@b@ if (Map.class.isAssignableFrom(type)) {@b@ // 由于传入的Map可能不可修改,重新构建一个Map@b@ Map newMap = new HashMap();@b@ newMap.putAll((Map) parameter);@b@ return pagedMap(newMap, skip, pageSize);@b@ }@b@@b@ if (IbatisPlugin.isPrimitive(delegate, type)) {@b@ return pagedPrimitive(parameter, skip, pageSize);@b@ }@b@@b@ // TODO list@b@@b@ // TODO handle null@b@ return pagedObject(parameter, skip, pageSize);@b@ }@b@@b@ private List<String> queryStatementsEnhanced = new ArrayList();@b@@b@ public List<String> getQueryStatementsEnhanced() {@b@ return queryStatementsEnhanced;@b@ }@b@@b@ public void setQueryStatementsEnhanced(List<String> queryStatementsEnhanced) {@b@ this.queryStatementsEnhanced = queryStatementsEnhanced;@b@ }@b@@b@}