以下代码,亲测有效,放心使用。

1、新建一个Interceptor去实现 org.apache.ibatis.plugin.Interceptor,然后重写intercept方法。


import java.sql.Connection;
import java.util.Map;
import java.util.Properties;

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;

/**
 * @author: zxy
 * @data: 2020年4月13日 上午9:00:02
 * @Description:  
 * type 拦截的类型 四大对象之一( Executor,ResultSetHandler,ParameterHandler,StatementHandler)
 * method 拦截的方法
 * args 参数,高版本需要加个Integer.class参数,不然会报错,低版本去掉即可
 **/
@Intercepts({
		@Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class }) })
public class MyBatisPageInterceptor implements Interceptor {

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		// 1、获取StatementHandler,默认是RoutingStatementHandler
		StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
		// 2、获取statementHandler包装类
		MetaObject metaObjectHandler = SystemMetaObject.forObject(statementHandler);
		// 3、获取查询接口映射的相关信息
		MappedStatement mappedStatement = (MappedStatement) metaObjectHandler.getValue("delegate.mappedStatement");
		String mapId = mappedStatement.getId();
		// 4、使用正则表达式,拦截com.xx.xx.xxByPage的请求方法
		if (mapId.matches(".+ByPage$")) {
			// 5、获取BoundSql,通过BoundSql获取sql语句和查询条件
			BoundSql boundSql = statementHandler.getBoundSql();
			String sql = boundSql.getSql();
			sql = getLimitSql(sql, boundSql);
			// 6、将构建完成的分页sql语句赋值个体'delegate.boundSql.sql'
			metaObjectHandler.setValue("delegate.boundSql.sql", sql);
		}
		return invocation.proceed();
	}

	/**
	 * 构建分页SQL语句
	 * 
	 * @param sql
	 * @param boundSql
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private String getLimitSql(String sql, BoundSql boundSql) {
		Map<String, Object> params = (Map<String, Object>) boundSql.getParameterObject();
		int pageNum = Integer.parseInt(params.get("pageNum").toString());//每页页码
		int pageSize = Integer.parseInt(params.get("pageSize").toString());//每页显示的数据行数
		StringBuilder sb = new StringBuilder();
		sb.append(" select ");
		sb.append(" * ");
		sb.append(" from ");
		sb.append(" ( select a.*, rownum rn from ");
		sb.append(" ( " + sql + " ) a where rownum <= ");
		sb.append(pageNum * pageSize);
		sb.append(" ) where rn> ");
		sb.append((pageNum - 1) * pageSize);
		return sb.toString();
	}

	/*
	 * 获取代理对象
	 * 
	 * @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)
	 */
	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	/*
	 * 设置代理对象参数
	 * 
	 * @see org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)
	 */
	@Override
	public void setProperties(Properties properties) {

	}

}

2、增加配置类,使拦截器生效


import org.apache.ibatis.plugin.Interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.success.web.interceptor.MyBatisPageInterceptor;

/**
 * @author: zxy
 * @data: 2020年4月13日 上午10:04:09
 * @Description: MyBatis配置类
 **/
@Configuration
public class MyBatisConfig {

	/**自定义拦截器
	 * @return
	 */
	@Bean
	public Interceptor getInterceptor() {
		return new MyBatisPageInterceptor();
	}
}

 

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐