You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aggregation-platform/src/com/platform/utils/page/PageInterceptor.java

201 lines
7.6 KiB

package com.platform.utils.page;
import java.sql.Connection;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.MappedStatement.Builder;
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.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
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.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import org.apache.log4j.Logger;
import com.platform.utils.Configs;
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}),
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class PageInterceptor implements Interceptor {
@SuppressWarnings("static-access")
public static Logger log = Configs.CONSOLE_LOGGER.getLogger(PageInterceptor.class);
/** 存储所有语句名称 */
/* HashMap<String, String> map_statement = new HashMap<String, String>();*/
/** 用户提供分页计算条数后缀 */
private static final String SELECT_ID="page";
@Override
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getTarget() instanceof StatementHandler) {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
MappedStatement mappedStatement=(MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
String selectId=mappedStatement.getId();
// System.out.println(" ---------- selectId ---- : " + selectId);
if(selectId.substring(selectId.lastIndexOf(".")+1).toLowerCase().endsWith(SELECT_ID)){
BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
// 分页参数作为参数对象parameterObject的一个属性
String sql = boundSql.getSql();
Page co=(Page)(boundSql.getParameterObject());
// 重写 Sql语句
log.info(sql.replaceAll("\n", "").replaceAll("\t\t", "\t"));
String countSql=concatCountSql(sql);
Connection connection = (Connection) invocation.getArgs()[0];
PreparedStatement countStmt = null;
ResultSet rs = null;
int totalCount = 0;
try {
//绑定数据
countStmt = connection.prepareStatement(countSql);
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,
boundSql.getParameterMappings(), boundSql.getParameterObject());
setParameters(countStmt, mappedStatement, countBS, boundSql.getParameterObject());
//执行
rs = countStmt.executeQuery();
if (rs.next()) {
totalCount = rs.getInt(1);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
countStmt.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//绑定count
co.setTotleSize(totalCount);
int totalPage = totalCount/co.getLimit();
if (totalCount > totalPage*co.getLimit()) {
totalPage+=1;
}
co.setTotlePage(totalPage);
if (co.getCurrentPageNum() > co.getTotlePage()) {
co.setCurrentPageNum(co.getTotlePage());
}
String pageSql=concatPageMySql(sql,co);
metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
}
}
return invocation.proceed();
}
/**
* <一句话功能简述> 重写sql
* <功能详细描述>
* @param sql
* @return
* @see [类、类#方法、类#成员]
*/
public String concatCountSql(String sql){
StringBuffer sb=new StringBuffer("select count(*) from ");
sql=sql.toLowerCase();
if(sql.lastIndexOf("order")>sql.lastIndexOf(")")){
sb.append(sql.substring(sql.indexOf("from")+4, sql.lastIndexOf("order")));
}else{
sb.append(sql.substring(sql.indexOf("from")+4));
}
return sb.toString();
}
/**
* <一句话功能简述> 重写sql
* <功能详细描述>
* @param sql
* @param page
* @return
* @see [类、类#方法、类#成员]
*/
public String concatPageMySql(String sql,Page page){
StringBuffer sb=new StringBuffer();
sb.append(sql);
int size = page.getLimit();
int index = page.getCurrentPageNum();
if (index > 1) {
index = index -1;
if (page.getTotlePage() == page.getCurrentPageNum()) {
sb.append(" limit ").append(size*index).append(" , ").append(page.getTotleSize()-(size*index));
}
else {
sb.append(" limit ").append(size*index).append(" , ").append(size);
}
}
else {
sb.append(" limit ").append(0).append(" , ").append(size);
}
return sb.toString();
}
/**
* 拦截类型StatementHandler
*/
@Override
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
}
/**
* 对SQL参数(?)设值
* @param ps
* @param mappedStatement
* @param boundSql
* @param parameterObject
* @throws SQLException
*/
private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql,
Object parameterObject) throws SQLException {
ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler.setParameters(ps);
}
}