美文网首页
基于Mybatis Plugin机制实现简单的分页机制

基于Mybatis Plugin机制实现简单的分页机制

作者: 艺术类架构师 | 来源:发表于2019-08-11 12:42 被阅读0次

    分页其实很简单。
    可以手写的。
    直接贴源代码好了。
    注:有仿照MybatisPlus的机制,仅供学些。

    第一步:写一个拦截器

    import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
    import org.apache.ibatis.binding.MapperMethod;
    import org.apache.ibatis.executor.statement.StatementHandler;
    import org.apache.ibatis.mapping.BoundSql;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.mapping.SqlCommandType;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.reflection.SystemMetaObject;
    import plus.pagination.DialectBuilder;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.*;
    
    /**
     * 参考了MP的分页机制,适合初学者学习入门使用
     * 适合初学者学习
     * Created by Administrator on 2019/8/10.
     */
    @Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
    public class CustPaginationInterceptor implements Interceptor {
    
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            MetaObject metaObject = SystemMetaObject.forObject(invocation.getTarget());
            MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
            if(mappedStatement.getSqlCommandType()== SqlCommandType.SELECT){
                    BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
                   Object paramObj = boundSql.getParameterObject();
                   Object castedObject= getPageParam(boundSql);
                    if(null==castedObject){
                        return  invocation.proceed();
                    }
                    Page page= (Page)castedObject;
                    String originalSql=boundSql.getSql();
                    String pageSql= DialectBuilder.pageAbleForH2Select(originalSql, page);
                    metaObject.setValue("delegate.boundSql.sql",pageSql);
                  //查询总条数
                    Connection connection= (Connection) invocation.getArgs()[0];
                    DbType dbType = JdbcUtils.getDbType(connection.getMetaData().getURL());
                    Statement statement= connection.createStatement();
                    //java 8+ try Resource机制会自动关闭资源
                    try (ResultSet resultSet = statement.executeQuery(String.format("select count(1) from  (%s)",originalSql))) {
                        if (resultSet.next()) {
                            Long total = resultSet.getLong(1);
                            page.setTotal(total);
                        }
                    }
    
             }
    
            return invocation.proceed();
        }
    
            private Page getPageParam(BoundSql boundSql){
               Object paramObject= boundSql.getParameterObject();
               if(paramObject instanceof MapperMethod.ParamMap||paramObject instanceof MapperMethod.ParamMap){
                   MapperMethod.ParamMap paramMap= (MapperMethod.ParamMap) paramObject;
                Set keySet=   paramMap.keySet();
                Iterator it=keySet.iterator();
                while (it.hasNext()){
                    if(paramMap.get(it.next()) instanceof  Page){
                        return (Page)paramMap.get(it.next()) ;
            
                    }
                }
               }
                if(boundSql.getParameterObject() instanceof  Page){
                    return (Page) boundSql.getParameterObject();
                }
                return null;
            }
    
        @Override
        public Object plugin(Object target) {
            if (target instanceof StatementHandler) {
                return Plugin.wrap(target, this);
            }
            return target;
        }
    
        @Override
        public void setProperties(Properties properties) {
    
          for (Map.Entry<Object, Object> entry:  properties.entrySet()){
              System.out.println(entry.getKey()+"="+entry.getValue());
          }
        }
    }
    
    package plus.pagination;
    
    import com.baomidou.mybatisplus.core.toolkit.Assert;
    import plus.Page;
    package plus.pagination;
    
    import com.baomidou.mybatisplus.core.toolkit.Assert;
    import plus.Page;
    
    /**
     * Created by Administrator on 2019/8/11.
     */
    public class DialectBuilder {
    
        public static String pageAbleForH2Select(String originalSql, Page page) {
            Assert.notNull(page, "the page Object must not be null");
            if (page.getCurrentPage() > 1) {
                return String.format("select * from ( %s) temp limit %d offset %d", originalSql, page.getPageSize() * page.getPageSize(), (page.getCurrentPage() - 1) * page.getPageSize());
            }
            return String.format("select * from %s limit %d", page.getPageSize());
        }
    }
    
    --Page对象
    package plus;
    
    import java.util.List;
    
    /**
     * Created by Administrator on 2019/8/10.
     */
    
    public class Page {
    
        private List records;
    
        private  Integer pageSize;
    
        private Long total;
    
        private String orderByColumn;
    
        private  Integer currentPage;
    
        public List getRecords() {
            return records;
        }
    
        public void setRecords(List records) {
            this.records = records;
        }
    
        public Integer getPageSize() {
            return pageSize;
        }
    
        public void setPageSize(Integer pageSize) {
            this.pageSize = pageSize;
        }
    
        public Long getTotal() {
            return total;
        }
    
        public void setTotal(Long total) {
            this.total = total;
        }
    
        public String getOrderByColumn() {
            return orderByColumn;
        }
    
        public void setOrderByColumn(String orderByColumn) {
            this.orderByColumn = orderByColumn;
        }
    
        public Integer getCurrentPage() {
            return currentPage;
        }
    
        public void setCurrentPage(Integer currentPage) {
            this.currentPage = currentPage;
        }
    
    }
    
    
    
    

    第二步:将拦截器添加至Mybatis的 configuration.addInterceptor(plugin)中去,可以配置或者代码中去实现,太简单了,所以忽视。

    到这里已经完成了分页了,下面给出在DAO层如何使用的示例。

    @Mapper
    public interface AccountMapper extends BaseMapper<Account>{
    
      @Select("select * from t_account")
      List<Account> selectAllAccountInfo(Page page,String param);
    }
    

    如何使用

    public List<Account> getReadAccountInfo(Page page ){

        return  userMapper.selectAllUserInfo(page,"");
    }
    

    仓库地址:https://github.com/Leeyongke/read-write
    谢谢观看。

    相关文章

      网友评论

          本文标题:基于Mybatis Plugin机制实现简单的分页机制

          本文链接:https://www.haomeiwen.com/subject/ognjjctx.html