mybatis-plus icon indicating copy to clipboard operation
mybatis-plus copied to clipboard

分页Page和ResultHandler一起使用

Open SKITE-Hello opened this issue 2 years ago • 6 comments

当前使用版本(必填,否则不予处理)

mybatis-plus-extension 3.5.1 mybatis-plus-core 3.5.1 mybatis3.5.6

该问题是如何引起的?(确定最新版也有问题再提!!!)

1.MybatisPlusInterceptor使用PaginationInnerInterceptor(DbType.MYSQL) 2.BaseResultHandler 实现 org.apache.ibatis.session.ResultHandler 3.在一个查询方法中同时使用了IPage和ResultHandler void msgSelect(IPage<BaseVO> page,@Param("dto") ReqDTO dto ,BaseResultHandler baseResultHandler);

重现步骤(如果有就写完整)

1.正常调用msgSelect方法; 2.程序会获取到BaseResultHandler ,然后在PaginationInnerInterceptor的willDoQuery方法中传递给executor.query()方法; 3.跟踪代码,当程序执行到DefaultResultSetHandler的handleResultSet()方法时,会判断resultHandler 是否为空,由于我传递了一个resultHandler ,所以此处会走else分支,会导致multipleResults最后没有值

private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {
    try {
      if (parentMapping != null) {
        handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
      } else {
        if (resultHandler == null) {
          DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
          handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
          multipleResults.add(defaultResultHandler.getResultList());
        } else {
          //实际走了这里,没有为multipleResults设置值
          handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
        }
      }
    } finally {
      // issue #228 (close resultsets)
      closeResultSet(rsw.getResultSet());
    }
  }
  1. 程序在DefaultResultSetHandler的handleResultSets()方法会返回multipleResults作为结果,但由于上述第三步的判断所以最终会返回一个空值,导致最后在PaginationInnerInterceptor的willDoQuery()方法中获取到的数据条数为0(实际不为0),程序就没有再执行后续操作了,即查询具体的结果。

报错信息

无法正确返回结果

SKITE-Hello avatar Apr 12 '22 03:04 SKITE-Hello

见第二部分

之后可以使用以下方式,处理自定义ResultHandler场景

package com.ruben.mybatisplusissue.handler;

import org.apache.ibatis.session.ResultContext;

import com.baomidou.mybatisplus.extension.plugins.handler.PageResultHandler;

public class MyBaseResultHandler<T> extends PageResultHandler<T> {

    @Override
    public void handleResult(ResultContext<? extends T> resultContext) {
        super.handleResult(resultContext);        
        // 接下来是你的逻辑
        
    }
}

感谢!

VampireAchao avatar Apr 19 '22 07:04 VampireAchao

你的BaseResultHandler代码怎么写的?

miemieYaho avatar Apr 19 '22 08:04 miemieYaho

代码如下

public class BaseResultHandler  implements ResultHandler<BaseVO> {
    private  List<BaseVO> list = new ArrayList<>();
    @Override
    public void handleResult(ResultContext<? extends BaseVO> resultContext) {
        final BaseVO resultObject = resultContext.getResultObject();
		// 做一些具体操作
        list.add(resultObject);
    }

    public List<BaseVO> getResult(){
        return list;
    }
}

SKITE-Hello avatar Apr 19 '22 08:04 SKITE-Hello

那最后你要自己把结果set到page里面吗?

miemieYaho avatar Apr 19 '22 09:04 miemieYaho

那最后你要自己把结果set到page里面吗?

是的,加了ResultHandler之后只能自己从ResultHandler里面把数据拿出来set到page里面了

SKITE-Hello avatar Apr 19 '22 09:04 SKITE-Hello

那最后你要自己把结果set到page里面吗?

如果后期可以支持直接把结果装载到page里面当然更好

SKITE-Hello avatar Apr 19 '22 09:04 SKITE-Hello