• 【报错记录】MybatisPlus报Mapped Statements collection does not contain value for...


    前言

    为了让我的SqlUtil用起来更香,我准备将SqlHelper中的saveOrUpdateBatch方法的参数从Class mapper换成mapper的实体类,再通过mapper.getClass()的方式获取其真实类。

    报错信息

    如果是批量插入会报:

    Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.sun.proxy.$Proxy129.insert

    如果是执行批量更新则会报:

    Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.sun.proxy.$Proxy129.updateById

    代码如下:

    1. public static extends BaseEntity, R extends BaseMapper> void saveBatch(Class mapperClass, List entityList, Long userId) {
    2. saveBatch(mapperClass, entityList, userId, 10000);
    3. }
    4. public static extends BaseEntity, R extends BaseMapper> void saveBatch(R mapper, List entityList, Long userId) {
    5. saveBatch(mapper.getClass(), entityList, userId, 10000);
    6. }
    7. public static extends BaseEntity, R extends BaseMapper> void saveBatch(Class mapperClass, List entityList, Long userId, int batchSize) {
    8. if (entityList.size() == 0) {
    9. return;
    10. }
    11. T t = entityList.get(0);
    12. Class entityClass = (Class) t.getClass();
    13. SqlHelper.saveOrUpdateBatch(entityClass, mapperClass, log, entityList, batchSize, (sqlSession, entity) -> {
    14. // INFO: DCTANT: 2021/12/27 insert判断,返回true则是走insert代码,返回false则会走后面的update代码
    15. if (entity == null) {
    16. return false;
    17. }
    18. Long id = entity.getId();
    19. if (id == null) {
    20. // INFO: DCTANT: 2021/12/27 insert前加一些自己必要的业务逻辑,如setCreateTime、setDel、setVersion等等
    21. insertNecessaryField(entity, userId);
    22. return true;
    23. } else {
    24. // INFO: DCTANT: 2021/12/27 去执行update的代码
    25. return false;
    26. }
    27. }, (sqlSession, entity) -> {
    28. // INFO: DCTANT: 2021/12/27 判断为update,然后执行必要操作
    29. if (entity == null) {
    30. return;
    31. }
    32. // INFO: DCTANT: 2021/12/27 update前加一些自己的业务逻辑,如setUpdateTime等等
    33. updateNecessaryField(entity, userId);
    34. MapperMethod.ParamMap param = new MapperMethod.ParamMap<>();
    35. // INFO: DCTANT: 2022/8/22 参数需要为Constants.ENTITY,也就是里面的et,否则会报et这个参数无法找到
    36. param.put(Constants.ENTITY, entity);
    37. String sqlStatement = SqlHelper.getSqlStatement(mapperClass, SqlMethod.UPDATE_BY_ID);
    38. sqlSession.update(sqlStatement, param);
    39. });
    40. }

    这个问题一开始报的让人摸不着头脑,若不是开了上帝视角,从前言中已经知道大概的问题原由,真是让人一头雾水,proxy类是哪来的,insert和updateById方法这两个方法在mapper中本来就有,凭什么会找不到!

    这里一共三种写法,其中2、3是等价的

     第一种写法打断点可得知拿到的就是Mapper它自己本身的类

    这种写法能够反射获取其中的insert和updateById方法。

    而第二、三种方法打断点获得的类是

    实际是Java的代理类,Proxy类,这里面哪会存在insert和updateById方法,这就是报错的原因。所以方法不能胡乱抽取,这种就属于得不偿失,且无解。只能将本身的Class传入才能不报错,删除刚才的saveBatch(Class mapperClass, List entityList, Long userId)这个方法即可。 

    如果大家有什么其他解法可以指出,本人虚心接受。

     

  • 相关阅读:
    Vue实现手机端界面的购物车案例
    React/Vue项目-请求文件封装(Axios,WebSocket)
    WordPress主题开发( 十三)之—— CSS 和 JavaScript 文件
    2021年山东省职业院校技能大赛中职组”网络安全“正式赛题
    《见识》
    【Android#8】Editext和软键盘的爱恨情仇:自定义底部输入框被部分遮挡+IM聊天界面输入框表情面板的跳变问题+
    无线充U型超声波电动牙刷方案开发
    解决QT信号在信号和槽连接前发出而导致槽函数未调用问题
    安卓12系统RK3588开发板接口介绍
    构建汛期智慧水利新生态:EasyCVR视频汇聚监控综合管理方案解析
  • 原文地址:https://blog.csdn.net/DCTANT/article/details/126468022