Java tutorial
/** * @(#)${file_name} ${date} * * Copyright (c) 2014-2015 BuShangBan (China) Int'l Co., Ltd * yongtai Road. pu dong District.Shanghai China * All rights reserved. * * This software is the confidential and proprietary information of BuShangBan (China) * Int'l Co., Ltd ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with BuShangBan (China). */ package com.bsb.cms.commons.page.interceptor; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Properties; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.mapping.SqlSource; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.scripting.defaults.DefaultParameterHandler; import org.apache.ibatis.session.RowBounds; import com.bsb.cms.commons.page.PageContext; import com.bsb.cms.commons.page.Pagination; /** * mybatis? * * @author hongjian.liu * @version 1.0.0 2014-6-4 * @since 1.0 */ @Intercepts({ @org.apache.ibatis.plugin.Signature(type = org.apache.ibatis.executor.Executor.class, method = "query", args = { MappedStatement.class, Object.class, RowBounds.class, org.apache.ibatis.session.ResultHandler.class }) }) public class PaginationInterceptor implements Interceptor { // log private static final Log log = LogFactory.getLog(PaginationInterceptor.class); // private static String dialect = ""; // ? private static String pageSqlId = ".*ListPage$"; // mapper.xml?ID(?) /* * (non-Javadoc) * * @see * org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin * .Invocation) */ @Override public Object intercept(Invocation invocation) throws Throwable { // ? MappedStatementBoundSql?sql? MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; if (mappedStatement.getId().matches(pageSqlId)) { // ?SQL Object parameter = invocation.getArgs()[1]; BoundSql boundSql = mappedStatement.getBoundSql(parameter); String originalSql = boundSql.getSql().trim(); Object parameterObject = boundSql.getParameterObject(); /* * if (parameterObject != null) { page = * (Page)ReflectHelper.isPage(parameterObject, "page"); } * * if ((page == null) && (context.isPagination())) { page = context; * } */ // Pagination page = null; PageContext page = PageContext.getContext(); // Page?? String countSql = getCountSql(originalSql); Connection connection = mappedStatement.getConfiguration().getEnvironment().getDataSource() .getConnection(); PreparedStatement countStmt = connection.prepareStatement(countSql); BoundSql countBS = copyFromBoundSql(mappedStatement, boundSql, countSql); log.debug("countSql=" + countSql); DefaultParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, countBS); parameterHandler.setParameters(countStmt); ResultSet rs = countStmt.executeQuery(); int totpage = 0; if (rs.next()) { totpage = rs.getInt(1); } rs.close(); countStmt.close(); connection.close();// TODO // page.init(totpage, page.getPageSize(), page.getCurrentPage()); if ((StringUtils.isNotEmpty(page.getOrderBy())) && (originalSql.indexOf("BUSINESS_CIRCLE") == -1)) { originalSql = originalSql + " ORDER BY " + page.getOrderBy(); } String pageSql = buildPageSqlForMysql(originalSql, page).toString(); BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, pageSql); MappedStatement newMs = copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql)); log.debug("newMs=" + pageSql); invocation.getArgs()[0] = newMs; } return invocation.proceed(); } /** * ?MappedStatement */ private MappedStatement copyFromMappedStatement(MappedStatement ms, SqlSource newSqlSource) { MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType()); builder.resource(ms.getResource()); builder.fetchSize(ms.getFetchSize()); builder.statementType(ms.getStatementType()); builder.keyGenerator(ms.getKeyGenerator()); String[] keyProperties = ms.getKeyProperties(); String keyProperty = ""; if ((keyProperties != null) && (keyProperties.length > 0)) for (String kp : keyProperties) keyProperty = keyProperty + "," + kp; if (StringUtils.isNotEmpty(keyProperty)) keyProperty = keyProperty.substring(1); builder.keyProperty(keyProperty); builder.timeout(ms.getTimeout()); builder.parameterMap(ms.getParameterMap()); builder.resultMaps(ms.getResultMaps()); builder.cache(ms.getCache()); MappedStatement newMs = builder.build(); return newMs; } /** * ?BoundSql */ private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) { BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject()); for (ParameterMapping mapping : boundSql.getParameterMappings()) { String prop = mapping.getProperty(); if (boundSql.hasAdditionalParameter(prop)) { newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop)); } } return newBoundSql; } /** * Sqllimit mysql * * @param sql * @param page * @return */ public StringBuilder buildPageSqlForMysql(String sql, Pagination page) { StringBuilder pageSql = new StringBuilder(100); String beginrow = String.valueOf((page.getCurrentPage() - 1) * page.getPageSize()); pageSql.append(sql); pageSql.append(" limit " + beginrow + "," + page.getPageSize()); return pageSql; } /** * ?Sql??Sql? */ private String getCountSql(String sql) { return "SELECT COUNT(*) FROM (" + sql + ") aliasForPage"; } public class BoundSqlSqlSource implements SqlSource { BoundSql boundSql; public BoundSqlSqlSource(BoundSql boundSql) { this.boundSql = boundSql; } public BoundSql getBoundSql(Object parameterObject) { return boundSql; } } /* * (non-Javadoc) * * @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object) */ @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } /* * (non-Javadoc) * * @see * org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties) */ @Override public void setProperties(Properties properties) { } }