mybatis-plus
mybatis-plus copied to clipboard
分页Page和ResultHandler一起使用
当前使用版本(必填,否则不予处理)
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());
}
}
- 程序在DefaultResultSetHandler的handleResultSets()方法会返回multipleResults作为结果,但由于上述第三步的判断所以最终会返回一个空值,导致最后在PaginationInnerInterceptor的willDoQuery()方法中获取到的数据条数为0(实际不为0),程序就没有再执行后续操作了,即查询具体的结果。
报错信息
无法正确返回结果
之后可以使用以下方式,处理自定义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);
// 接下来是你的逻辑
}
}
感谢!
你的BaseResultHandler代码怎么写的?
代码如下
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;
}
}
那最后你要自己把结果set到page里面吗?
那最后你要自己把结果set到page里面吗?
是的,加了ResultHandler之后只能自己从ResultHandler里面把数据拿出来set到page里面了
那最后你要自己把结果set到page里面吗?
如果后期可以支持直接把结果装载到page里面当然更好