自定义Mybatis分页插件

1、通过ThreadLocal封装分页

  • 线程分页参数:
public class PageThreadLocalUtil {

    private static final ThreadLocal<BasePage> PAGE_THREAD_LOCAL = new ThreadLocal();

    public static void setPageThreadLocal(BasePage basePage) {
        PAGE_THREAD_LOCAL.set(basePage);
    }

    public static void getPageThreadLocal() {
        PAGE_THREAD_LOCAL.get();
    }

    public static void removePageThreadLocal() {
        PAGE_THREAD_LOCAL.remove();
    }

    public static void init(int start, int size) {
        BasePage basePage = new BasePage();
        basePage.setStart(start);
        basePage.setSize(size);
        setPageThreadLocal(basePage);
    }
}
  • 分页参数:
@Data
public class BasePage<T> implements Serializable {

    private Integer start;

    private Integer size;

    private Integer total;

    private boolean flag;
}
  • 自定义拦截器:

拦截器配置:

在这里插入图片描述

//@Intercepts({@Signature(
// type = Executor.class,
// method = “query”,
// args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }) })

@Intercepts(@Signature(
            type = StatementHandler.class,
            method = "prepare",
            args = {Connection.class, Integer.class}))
public class MyPageHelper implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
       	// map.xml对应id
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        String statementId = mappedStatement.getId();

        // 获取StatementHandler中的变量: 判断是否为查询:select
        String trimSql = (String) metaObject.getValue("delegate.boundSql.sql");
        int index = trimSql.trim().toLowerCase().indexOf("select");
        if (index != 0) {
            return invocation.proceed();
        }	
		BasePage page = PageThreadLocalUtil.getPageThreadLocal();
		if(!page.getFlag()) {
		   return invocation.proceed();
		}
   
        // 数量查询
        String sql = statementHandler.getBoundSql().getSql();
        String countSql = "select count(*) " + sql.substring(sql.toLowerCase().indexOf("from"));
        Connection connection = (Connection) invocation.getArgs()[0];
        PreparedStatement ps = connection.prepareStatement(countSql);
        //渲染参数
        ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");;
        parameterHandler.setParameters(ps);
        ResultSet resultSet = ps.executeQuery();
        if(resultSet.next()){
            page .setTotal(resultSet.getInt(1));
        }
		int start = page.getStart()
        int size = page.getSize()
        String pageSql = sql + " limit " + start + "," + size + "";
        metaObject.setValue("delegate.boundSql.sql", pageSql);
        return invocation.proceed();
    }
}

2、封装分页查询参数BasePage

  • 查询参数继承BasePage
@Intercepts(@Signature(
            type = StatementHandler.class,
            method = "prepare",
            args = {Connection.class, Integer.class}))
public class MyPageHelper implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,
                SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());

    
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        String statementId = mappedStatement.getId();

        String trimSql = (String) metaObject.getValue("delegate.boundSql.sql");
        int index = trimSql.trim().toLowerCase().indexOf("select");
        if (index != 0) {
            return invocation.proceed();
        }

        
        // 获取传入分页参数,  [类型必须与参数类型一致]
        // Object parameterObject = parameterHandler.getParameterObject();
        // List<ParameterMapping> parameterMappings = statementHandler.getBoundSql().getParameterMappings();
        Object parameterObject1 = statementHandler.getBoundSql().getParameterObject();
        BasePage page = findPageObject(parameterObject1);
        if(page == null) {
        	return invocation.proceed();
        }
        int  size = page.getSize();
        int  start = page.getStart();
                
        // 数量查询
        String sql = statementHandler.getBoundSql().getSql();
        String countSql = "select count(*) " + sql.substring(sql.toLowerCase().indexOf("from"));
        Connection connection = (Connection) invocation.getArgs()[0];
        PreparedStatement ps = connection.prepareStatement(countSql);
        //渲染参数
        ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");;
        parameterHandler.setParameters(ps);
        ResultSet resultSet = ps.executeQuery();
        if(resultSet.next()){
            page.setTotal(resultSet.getInt(1));
        }

        String pageSql = sql + " limit " + start + "," + size + "";
        metaObject.setValue("delegate.boundSql.sql", pageSql);
        return invocation.proceed();
    }


    private BasePage<?> findPageObject(Object parameterObj) {
        if (parameterObj instanceof BasePage<?>) {
            return (BasePage<?>) parameterObj;
        } else if (parameterObj instanceof Map) {
            for (Object val : ((Map<?, ?>) parameterObj).values()) {
                if (val instanceof BasePage<?>) {
                    return (BasePage<?>) val;
                }
            }
        }
        return null;
    }

}

参考文档:

Mybatis官网-插件(plugins)
mybatis插件机制及分页插件原理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值