mybatis - 使用Mybatis Plus打包批量查询报错
问题描述
使用Mybatis Plus打包批量查询报错
场景
我需要封装一个可以根据对象列表查询的通用方法,所以写了如下方法。注意:这个类继承了 IServiceImpl
Public List<T> listBatchByEntityList(List<T> entityList) {
Try (final SqlSession batchSqlSession = sqlSessionBatch()) {
Final int size = entityList.size();
Final int batchSize = 30;
Final List<T> result = new ArrayList<>();
For (int i = 0; i < size; i++) {
Final String sqlStatement = sqlStatement(SqlMethod.SELECT_LIST);
Final List<T> list = batchSqlSession.selectList(sqlStatement, new EntityWrapper<>(entityList.get(i)));
result.addAll(list);
If (i >= 1 && i % batchSize == 0) {
batchSqlSession.flushStatements();
}
}
batchSqlSession.flushStatements();
Return result;
} catch (Exception e) {
Throw new GlobalException("Error: Cannot execute listBatchByEntityList Method. Cause", e);
}
}
但是,在运行时发生了异常。
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'ew' in 'class com.baomidou.mybatisplus.mapper.EntityWrapper'
### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'ew' in 'class com.baomidou.mybatisplus.mapper.EntityWrapper'
At org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
At org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)
At org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)
At com.zx.idc.ds.common.service.impl.BaseServiceImpl.listBatchByEntityList(BaseServiceImpl.java:54)
... 37 more
Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'ew' in 'class com.baomidou.mybatisplus.mapper.EntityWrapper'
At org.apache.ibatis.reflection.Reflector.getGetInvoker(Reflector.java:419)
At org.apache.ibatis.reflection.MetaClass.getGetInvoker(MetaClass.java:164)
At org.apache.ibatis.reflection.wrapper.BeanWrapper.getBeanProperty(BeanWrapper.java:162)
At org.apache.ibatis.reflection.wrapper.BeanWrapper.get(BeanWrapper.java:49)
At org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122)
At org.apache.ibatis.scripting.xmltags.DynamicContext$ContextMap.get(DynamicContext.java:94)
At org.apache.ibatis.scripting.xmltags.DynamicContext$ContextAccessor.getProperty(DynamicContext.java:108)
At org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:2685)
At org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:114)
At org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
At org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
At org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:50)
At org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
At org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
At org.apache.ibatis.ognl.ASTAnd.getValueBody(ASTAnd.java:61)
At org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
At org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
At org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:470)
At org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:434)
At org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:44)
At org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)
At org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34)
At org.apache.ibatis.scripting.xmltags.ChooseSqlNode.apply(ChooseSqlNode.java:35)
At org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33)
At org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:41)
At org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:292)
At org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:134)
At org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)
... 39 more
有没有人遇到过这种情况?
解决方案
这么晚才回复很抱歉。
问题是:您调用了batchSqlSession.selectList并直接使用了参数,但是在mybatis-plus(2.x)中baseMapper.selectList(@Param(“ew”)Wrapper ew)中的方法,参数具有注释@Param ,它将由 org.apache.ibatis.reflection.ParamNameResolver(line 121 @mybatis-3.4.6) 处理并包装为 ParamMap。
所以解决方法很简单:
一些代码更改:
final Map<String, Object> param = new MapperMethod.ParamMap<Object>();
EntityWrapper<T> ew = new EntityWrapper<>(entityList.get(i));
param.put("ew", ew);
param.put("param1", ew);
final List<T> list = batchSqlSession.selectList(sqlStatement, param);
完整代码如下:
public List<T> listBatchByEntityList(List<T> entityList) {
try (final SqlSession batchSqlSession = sqlSessionBatch()) {
final int size = entityList.size();
final int batchSize = 30;
final List<T> result = new ArrayList<>();
for (int i = 0; i < size; i++) {
final String sqlStatement = sqlStatement(SqlMethod.SELECT_LIST);
final Map<String, Object> param = new MapperMethod.ParamMap<Object>();
EntityWrapper<T> ew = new EntityWrapper<>(entityList.get(i));
param.put("ew", ew);
param.put("param1", ew);
final List<T> list = batchSqlSession.selectList(sqlStatement, param);
result.addAll(list);
if (i >= 1 && i % batchSize == 0) {
batchSqlSession.flushStatements();
}
}
batchSqlSession.flushStatements();
return result;
} catch (Exception e) {
throw new GlobalException("Error: Cannot execute listBatchByEntityList Method. Cause", e);
}
}
测试正常。
顺便说一句,请随时在https://github.com/baomidou/mybatis-plus/issues上提出问题,无论使用 mybatis-plus 遇到什么错误
问候
Mybatis-plus 的成员 :)
推荐阅读
- vba - 如何在编辑 MSAccess 表单文本框时获取“值”属性?
- sql - 在存储过程中查找和使用值
- android - Android以编程方式更改按钮的背景
- react-router - 如何在 React Router v5 中保留重定向查询参数
- google-app-engine - 如何让 Google Cloud Platform App EngineStandard 访问非安全端点
- python - 用于句子的 Pytorch 数据加载器
- reactjs - 如何在宽度和高度较小的圆形下拉菜单中显示内容
- php - PHPMailer Gmail 登录失败,尽管将端口设置为 465 调整“访问不太安全的应用程序”并使用“DisplayUnlockCaptcha”
- graphql - GraphQL.Net - 防止突变异常的空数据
- r - 在 R 中为具有 3 个不同条件的 3 个不同变量创建一个 for 循环