mybatis分页插件demo

162 阅读1分钟

[mybtais插件原理看上篇]("mybatis插件原理简述 - 掘金 (juejin.cn)")

1、分页插件核心

/**
 * mybatis分页插件dome
 */
@Intercepts(@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class,Integer.class}))
public class PageIntercept implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        // 针对定义了rowBounds,做为mapper接口方法的参数
        BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
        Object paramObj = boundSql.getParameterObject();
        String originalSql = boundSql.getSql();
        IPage page = null;
        //尝试获取参数中的 IPage
        if (paramObj instanceof IPage) {
            page = (IPage) paramObj;
        } else if (paramObj instanceof Map) {
            for (Object arg : ((Map<?, ?>) paramObj).values()) {
                if (arg instanceof IPage) {
                    page = (IPage) arg;
                    break;
                }
            }
        }
        //没有分页参数直接返回
        if (page!=null){
            originalSql=originalSql+" LIMIT "+page.getPage()*page.getSize()+","+page.getSize();
            //还是通过反射赋值,但是Method类是从缓存中取的
            metaObject.setValue("delegate.boundSql.sql", originalSql);
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

2、IPage分页参数包装类

/**
 * @program: mybatis
 * @description: <p>描述</p>
 * @create: 2022/03/01
 **/
public class IPage {
    private int page;
    private int size=10;
    private int tatol;

    public IPage() {
    }

    public IPage(int page, int size) {
        this.page = page;
        this.size = size;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public int getTatol() {
        return tatol;
    }

    public void setTatol(int tatol) {
        this.tatol = tatol;
    }
}

3、从mybatis-plush中拿的参数获取工具类

/**
 * @program: mybatis
 * @description: <p>描述</p>
 * @author: MT.xwq
 * @create: 2022/03/01
 **/
public final class PluginUtils {
    public static final String DELEGATE_BOUNDSQL_SQL = "delegate.boundSql.sql";

    private PluginUtils() {
        // to do nothing
    }

    /**
     * 获得真正的处理对象,可能多层代理.
     */
    @SuppressWarnings("unchecked")
    public static <T> T realTarget(Object target) {
        if (Proxy.isProxyClass(target.getClass())) {
            MetaObject metaObject = SystemMetaObject.forObject(target);
            return realTarget(metaObject.getValue("h.target"));
        }
        return (T) target;
    }

    /**
     * 根据 key 获取 Properties 的值
     */
    public static String getProperty(Properties properties, String key) {
        String value = properties.getProperty(key);
        return StringUtils.isEmpty(value) ? null : value;
    }
}