1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| @Intercepts({@Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} )}) public class OffsetLimitInterceptor implements Interceptor {
@Override public Object intercept(Invocation invocation) throws Throwable { Object[] args = invocation.getArgs(); RowBounds rowBounds = (RowBounds) args[2]; PageParam pageParam = new PageParam(rowBounds); if (pageParam.getOffset() == 0 && pageParam.getLimit() == Integer.MAX_VALUE) { return invocation.proceed(); } Executor executor = (Executor) invocation.getTarget(); MappedStatement ms = (MappedStatement) args[0]; Object parameter = args[1]; BoundSql boundSql = ms.getBoundSql(parameter); Field additionalParamsField = BoundSql.class.getDeclaredField("additionalParameters"); additionalParamsField.setAccessible(true); Map<String, Object> additionalParams = (Map<String, Object>) additionalParamsField.get(boundSql); if (rowBounds instanceof PageParam) { MappedStatement countMs = newMappedStatement(ms, Integer.class); String countSql = "SELECT COUNT(*) FROM (" + boundSql.getSql() + ") temp"; BoundSql countBoundSql = new BoundSql(ms.getConfiguration(), countSql, boundSql.getParameterMappings(), parameter); for (String key : additionalParams.keySet()) { countBoundSql.setAdditionalParameter(key, additionalParams.get(key)); } CacheKey countCacheKey = executor.createCacheKey(countMs, parameter, RowBounds.DEFAULT, countBoundSql); List<Object> countResult = executor.query(countMs, parameter, RowBounds.DEFAULT, (ResultHandler) args[3], countCacheKey, countBoundSql); int totalCount = (int) countResult.get(0); pageParam.setTotalCount(totalCount); } String pageSql = boundSql.getSql() + " LIMIT " + pageParam.getOffset() + "," + pageParam.getLimit(); BoundSql pageBoundSql = new BoundSql(ms.getConfiguration(), pageSql, boundSql.getParameterMappings(), parameter); for (String key : additionalParams.keySet()) { pageBoundSql.setAdditionalParameter(key, additionalParams.get(key)); } CacheKey pageCacheKey = executor.createCacheKey(ms, parameter, rowBounds, pageBoundSql); List<?> pageResult = executor.query(ms, parameter, RowBounds.DEFAULT, (ResultHandler) args[3], pageCacheKey, pageBoundSql); return new Page<>(pageResult, pageParam); }
private MappedStatement newMappedStatement(MappedStatement ms, Class<Integer> resultType) { MappedStatement.Builder builder = new MappedStatement.Builder( ms.getConfiguration(), ms.getId() + "_count", ms.getSqlSource(), ms.getSqlCommandType() ); ResultMap countResultMap = new ResultMap.Builder( ms.getConfiguration(), ms.getId() + "_count_result", resultType, new ArrayList<>() ).build(); builder.resource(ms.getResource()) .parameterMap(ms.getParameterMap()) .resultMaps(Arrays.asList(countResultMap)) .useCache(ms.isUseCache()) .cache(ms.getCache()); return builder.build(); }
}
|
v1.3.10