Java tutorial
/* * The MIT License (MIT) * * Copyright (c) 2014-2017 abel533@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.github.pagehelper; import com.github.pagehelper.cache.Cache; import com.github.pagehelper.cache.CacheFactory; import com.github.pagehelper.util.MSUtils; import com.github.pagehelper.util.StringUtil; import org.apache.ibatis.cache.CacheKey; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Properties; /** * Mybatis - <br/> * ? : http://git.oschina.net/free/Mybatis_PageHelper * * @author liuzh/abel533/isea533 * @version 5.0.0 */ @SuppressWarnings({ "rawtypes", "unchecked" }) @Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }), @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class }), }) public class PageInterceptor implements Interceptor { //countms protected Cache<CacheKey, MappedStatement> msCountMap = null; private Dialect dialect; private String default_dialect_class = "com.github.pagehelper.PageHelper"; private Field additionalParametersField; @Override public Object intercept(Invocation invocation) throws Throwable { try { Object[] args = invocation.getArgs(); MappedStatement ms = (MappedStatement) args[0]; Object parameter = args[1]; RowBounds rowBounds = (RowBounds) args[2]; ResultHandler resultHandler = (ResultHandler) args[3]; Executor executor = (Executor) invocation.getTarget(); CacheKey cacheKey; BoundSql boundSql; //? if (args.length == 4) { //4 ? boundSql = ms.getBoundSql(parameter); cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql); } else { //6 ? cacheKey = (CacheKey) args[4]; boundSql = (BoundSql) args[5]; } List resultList; //???? if (!dialect.skip(ms, parameter, rowBounds)) { //????? Map<String, Object> additionalParameters = (Map<String, Object>) additionalParametersField .get(boundSql); //?? count if (dialect.beforeCount(ms, parameter, rowBounds)) { // count key CacheKey countKey = executor.createCacheKey(ms, parameter, RowBounds.DEFAULT, boundSql); countKey.update(MSUtils.COUNT); MappedStatement countMs = msCountMap.get(countKey); if (countMs == null) { //?? ms Long ms countMs = MSUtils.newCountMappedStatement(ms); msCountMap.put(countKey, countMs); } //? count sql String countSql = dialect.getCountSql(ms, boundSql, parameter, rowBounds, countKey); BoundSql countBoundSql = new BoundSql(ms.getConfiguration(), countSql, boundSql.getParameterMappings(), parameter); //? SQL ???? BoundSql for (String key : additionalParameters.keySet()) { countBoundSql.setAdditionalParameter(key, additionalParameters.get(key)); } // count Object countResultList = executor.query(countMs, parameter, RowBounds.DEFAULT, resultHandler, countKey, countBoundSql); Long count = (Long) ((List) countResultList).get(0); //? // true false if (!dialect.afterCount(count, parameter, rowBounds)) { // 0 return dialect.afterPage(new ArrayList(), parameter, rowBounds); } } //?? if (dialect.beforePage(ms, parameter, rowBounds)) { //? key CacheKey pageKey = cacheKey; //?? parameter = dialect.processParameterObject(ms, parameter, boundSql, pageKey); //? sql String pageSql = dialect.getPageSql(ms, boundSql, parameter, rowBounds, pageKey); BoundSql pageBoundSql = new BoundSql(ms.getConfiguration(), pageSql, boundSql.getParameterMappings(), parameter); //?? for (String key : additionalParameters.keySet()) { pageBoundSql.setAdditionalParameter(key, additionalParameters.get(key)); } // resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, pageKey, pageBoundSql); } else { //?? resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, boundSql); } } else { //rowBounds?????? resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql); } return dialect.afterPage(resultList, parameter, rowBounds); } finally { dialect.afterAll(); } } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { // count ms msCountMap = CacheFactory.createCache(properties.getProperty("msCountCache"), "ms", properties); String dialectClass = properties.getProperty("dialect"); if (StringUtil.isEmpty(dialectClass)) { dialectClass = default_dialect_class; } try { Class<?> aClass = Class.forName(dialectClass); dialect = (Dialect) aClass.newInstance(); } catch (Exception e) { throw new PageException(e); } dialect.setProperties(properties); try { //??? BoundSql additionalParameters additionalParametersField = BoundSql.class.getDeclaredField("additionalParameters"); additionalParametersField.setAccessible(true); } catch (NoSuchFieldException e) { throw new PageException(e); } } }