分页插件

分页插件其实就是使用代理模式的思想去实现的分页,直接上代码

分页实体类:

public class Page<E> implements Serializable {
    private static final long serialVersionUID = -5221494322324250056L;
       private int pageNum;
       private int pageSize;
       private int startRow;
       private int endRow;
       private long total;
       private int pages;
       private List<E> result;
       
       
       public Page() {
         super();
      }
      public Page(int pageNum, int pageSize, List<E> result) {
         super();
         this.pageNum = pageNum;
         this.pageSize = pageSize;
         this.result = result;
      }
      public Page(int pageNum, int pageSize) {
           this.pageNum = pageNum;
           this.pageSize = pageSize;
           this.startRow = pageNum > 0 ? (pageNum - 1) * pageSize : 0;
           this.endRow = pageNum * pageSize;
       }
       public List<E> getResult() {
           return result;
       }
       public void setResult(List<E> result) {
           this.result = result;
       }
       public int getPages() {
           return pages;
       }
       public void setPages(int pages) {
           this.pages = pages;
       }
       public int getEndRow() {
           return endRow;
       }
       public void setEndRow(int endRow) {
           this.endRow = endRow;
       }
       public int getPageNum() {
           return pageNum;
       }
       public void setPageNum(int pageNum) {
           this.pageNum = pageNum;
       }
       public int getPageSize() {
           return pageSize;
       }
       public void setPageSize(int pageSize) {
           this.pageSize = pageSize;
       }
       public int getStartRow() {
           return startRow;
       }
       public void setStartRow(int startRow) {
           this.startRow = startRow;
       }
       public long getTotal() {
           return total;
       }
       public void setTotal(long total) {
           this.total = total;
       }
      @Override
      public String toString() {
         return "Page [pageNum=" + pageNum + ", pageSize=" + pageSize
               + ", startRow=" + startRow + ", endRow=" + endRow
               + ", total=" + total + ", pages=" + pages + ", result="
               + result + "]";
      }
       
       
}

 

@SuppressWarnings("rawtypes")
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class,Integer.class }),
    @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
public class MyPageHelper implements Interceptor {
    private Logger logger=LoggerFactory.getLogger(MyPageHelper.class);
    public static final ThreadLocal<Page> localPage = new ThreadLocal<Page>();
       /**
        * 开始分页
        * @param pageNum
        * @param pageSize
        */
       public static void startPage(int pageNum, int pageSize) {
           localPage.set(new Page(pageNum, pageSize));
       }
       /**
        * 结束分页并返回结果,该方法必须被调用,否则localPage会一直保存下去,直到下一次startPage
        * @return
        */
       public static Page endPage() {
           Page page = localPage.get();
           localPage.remove();
           return page;
       }
       @SuppressWarnings("unchecked")
      @Override
       public Object intercept(Invocation invocation) throws Throwable {
           if (localPage.get() == null) {
               return invocation.proceed();
           }
           if (invocation.getTarget() instanceof StatementHandler) {
               StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
               MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
               // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环
               // 可以分离出最原始的的目标类)
               while (metaStatementHandler.hasGetter("h")) {
                   Object object = metaStatementHandler.getValue("h");
                   metaStatementHandler = SystemMetaObject.forObject(object);
               }
               // 分离最后一个代理对象的目标类
               while (metaStatementHandler.hasGetter("target")) {
                   Object object = metaStatementHandler.getValue("target");
                   metaStatementHandler = SystemMetaObject.forObject(object);
               }
               MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
               //分页信息if (localPage.get() != null) {
               Page page = localPage.get();
               BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
               // 分页参数作为参数对象parameterObject的一个属性
               String sql = boundSql.getSql();
               // 重写sql
               String pageSql = buildPageSql(sql, page);
               //重写分页sql
               metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
               Connection connection = (Connection) invocation.getArgs()[0];
               // 重设分页参数里的总页数等
               setPageParameter(sql, connection, mappedStatement, boundSql, page);
               // 将执行权交给下一个拦截器
               return invocation.proceed();
           } else if (invocation.getTarget() instanceof ResultSetHandler) {
              Object result = invocation.proceed();
               Page page = localPage.get();
               page.setResult((List) result);
               return result;
           }
           return null;
       }
       /**
        * 只拦截这两种类型的
        * <br>StatementHandler
        * <br>ResultSetHandler
        * @param target
        * @return
        */
       @Override
       public Object plugin(Object target) {
           if (target instanceof StatementHandler || target instanceof ResultSetHandler) {
               return Plugin.wrap(target, this);
           } else {
               return target;
           }
       }
       @Override
       public void setProperties(Properties properties) {
       }
       /**
        * 修改原SQL为分页SQL
        * @param sql
        * @param page
        * @return
        */
       private String buildPageSql(String sql, Page page) {
           StringBuilder pageSql = new StringBuilder(200);
           pageSql.append("select * from ( select temp.* from ( ");
           pageSql.append(sql);
           pageSql.append(" ) temp ) tt limit ").append(page.getStartRow());
           pageSql.append(",").append(page.getPageSize());
           return pageSql.toString();
       }
       /**
        * 获取总记录数
        * @param sql
        * @param connection
        * @param mappedStatement
        * @param boundSql
        * @param page
        */
       private void setPageParameter(String sql, Connection connection, MappedStatement mappedStatement,
                                     BoundSql boundSql, Page page) {
           // 记录总记录数
           String countSql = "select count(0) from (" + sql + ") temp";
           PreparedStatement countStmt = null;
           ResultSet rs = null;
           try {
               countStmt = (PreparedStatement) connection.prepareStatement(countSql);
               BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,
                       boundSql.getParameterMappings(), boundSql.getParameterObject());
               setParameters(countStmt, mappedStatement, countBS, boundSql.getParameterObject());
               rs = countStmt.executeQuery();
               int totalCount = 0;
               if (rs.next()) {
                   totalCount = rs.getInt(1);
               }
               page.setTotal(totalCount);
               int totalPage = totalCount / page.getPageSize() + ((totalCount % page.getPageSize() == 0) ? 0 : 1);
               page.setPages(totalPage);
           } catch (SQLException e) {
               logger.error("Ignore this exception", e);
           } finally {
               try {
                   rs.close();
               } catch (SQLException e) {
                   logger.error("Ignore this exception", e);
               }
               try {
                   countStmt.close();
               } catch (SQLException e) {
                   logger.error("Ignore this exception", e);
               }
           }
       }
       /**
        * 代入参数值
        * @param ps
        * @param mappedStatement
        * @param boundSql
        * @param parameterObject
        * @throws SQLException
        */
       private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql,
                                  Object parameterObject) throws SQLException {
           ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
           parameterHandler.setParameters(ps);
       }

   
}

 

具体使用实例,需要根据自己的业务场景来使用

MyPageHelper.startPage(Integer.valueOf(upstreamContractBillPO.getPageNum()),Integer.valueOf(upstreamContractBillPO.getPageSize()));
List <UpstreamContractBillRO> upstreamContractBillROS = tNewUpstreamContractBillExtendMapper.selectUpstreamContractBillList(upstreamContractBillPO);
page = MyPageHelper.endPage();

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值