@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})})public class PagePlugin implements Interceptor { private static String dialect = ""; //数据库方言 private static String pageSqlId = ""; //mapper.xml中需要拦截的ID(正则匹配) public Object intercept(Invocation ivk) throws Throwable { // TODO Auto-generated method stub if(ivk.getTarget() instanceof RoutingStatementHandler){ RoutingStatementHandler statementHandler = (RoutingStatementHandler)ivk.getTarget(); BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate"); MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement");
if(mappedStatement.getId().matches(pageSqlId)){ //拦截需要分页的SQLBoundSql boundSql = delegate.getBoundSql();Object parameterObject = boundSql.getParameterObject();//分页SQL
else{Connection connection = (Connection) ivk.getArgs()[0];String sql = boundSql.getSql();//String countSql = "select count(0) from (" + sql+ ") as tmp_count"; //记录统计String fhsql = sql;String countSql = "select count(0) from (" + fhsql+ ") tmp_count"; //记录统计 == oracle 加 as 报错(SQL command not properly ended)PreparedStatement countStmt = connection.prepareStatement(countSql);
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(),countSql,boundSql.getParameterMappings(),parameterObject);setParameters(countStmt,mappedStatement,countBS,parameterObject);ResultSet rs = countStmt.executeQuery();int count = 0;if (rs.next()) {count = rs.getInt(1);}
rs.close();countStmt.close();//System.out.println(count);Page page = null;if(parameterObject instanceof Page){ //参数就是Page实体page = (Page) parameterObject;page.setEntityOrField(true); page.setTotalResult(count);}else{ //参数为某个实体,该实体拥有Page属性Field pageField = ReflectHelper.getFieldByFieldName(parameterObject,"page");
if(pageField!=null){page = (Page) ReflectHelper.getValueByFieldName(parameterObject,"page");if(page==null)page = new Page();page.setEntityOrField(false); page.setTotalResult(count);ReflectHelper.setValueByFieldName(parameterObject,"page", page); //通过反射,对实体对象设置分页对象}else{throw new NoSuchFieldException(parameterObject.getClass().getName()+"不存在 page 属性!");}}String pageSql = generatePageSql(sql,page);ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); //将分页sql语句反射回BoundSql.}}}return ivk.proceed();}/*** 对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler* @param ps* @param mappedStatement* @param boundSql* @param parameterObject* @throws SQLException*/private void setParameters(PreparedStatement ps,MappedStatement mappedStatement,BoundSql boundSql,Object parameterObject) throws SQLException {ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());List
public void setProperties(Properties p) {dialect = p.getProperty("dialect");if (Tools.isEmpty(dialect)) {try {throw new PropertyException("dialect property is not found!");} catch (PropertyException e) {// TODO Auto-generated catch blocke.printStackTrace();}}pageSqlId = p.getProperty("pageSqlId");if (Tools.isEmpty(pageSqlId)) {try {throw new PropertyException("pageSqlId property is not found!");} catch (PropertyException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}