美文网首页
mybatis-plus 传参报错Type handler wa

mybatis-plus 传参报错Type handler wa

作者: 梅斋竹韵 | 来源:发表于2022-05-26 16:08 被阅读0次

    报错日志:

    Caused by: org.apache.ibatis.exceptions.PersistenceException: 
    ### Error querying database.  Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_value_0'. It was either not specified and/or could not be found for the javaType (com.pajx.pubc.kit.wrapper.IWrapper) : jdbcType (null) combination.
    ### Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property '__frch_value_0'. It was either not specified and/or could not be found for the javaType (com.pajx.pubc.kit.wrapper.IWrapper) : jdbcType (null) combination.
        at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
        ... 120 common frames omitted 
    

    起因:使用foreach进行查询操作,按照公司规范化封装方式性传参,一直报错!!检查传参类型、参数名称都无误【o(╥﹏╥)o】

    • 实现类
           // IWrapper  参数是list查询时,需要封装两层
       public List<IWrapper> list(IWrapper wrapper, String dealStatus) {
            return alarmEventMapper.list(wrapper.set("wrapper", IWrapper.create()), dealStatus);
        }
    
    • Mapper
     List<IWrapper> list(@Param("wrapper") IWrapper wrapper, @Param("wrapper") String dealStatus);
    

    原因:传参个数造成的,需要改变参数传入构造方式

    • 改变实现类
        // IWrapper 单层参数
       public List<IWrapper> list(IWrapper wrapper, String dealStatus) {
            return alarmEventMapper.list(wrapper), dealStatus);
        }
    

    程序访问没有问题了。。。Why?头疼o(╥﹏╥)o
    后来去看了下调用源码发现,mybatis在参数大于一个时,会再次封装参数为Map
    源码如下:【重点在else】

      public Object getNamedParams(Object[] args) {                                               
          int paramCount = this.names.size();                                                     
          if (args != null && paramCount != 0) {                                                  
              if (!this.hasParamAnnotation && paramCount == 1) {                                  
                  return args[(Integer)this.names.firstKey()];                                    
              } else {                                                                            
                  Map<String, Object> param = new ParamMap();                                     
                  int i = 0;                                                                      
                                                                                                  
                  for(Iterator var5 = this.names.entrySet().iterator(); var5.hasNext(); ++i) {    
                      Entry<Integer, String> entry = (Entry)var5.next();                          
                      param.put((String)entry.getValue(), args[(Integer)entry.getKey()]);         
                      String genericParamName = "param" + (i + 1);                                
                      if (!this.names.containsValue(genericParamName)) {                          
                          param.put(genericParamName, args[(Integer)entry.getKey()]);             
                      }                                                                           
                  }                                                                               
                                                                                                  
                  return param;                                                                   
              }                                                                                   
          } else {                                                                                
              return null;                                                                        
          }                                                                                       
    

    debugger源码调流程:


    image.png

    mybatis在使用Mapper进行编程时,其实际是通过MybatisMapperProxy代理机制,调用的SqlSession对应方法(例如:selectOne(),selectList()),会把参数进行校验和重新封装,导致sql执行中参数不一致报错!
    就这么无厘头的解决了,O(∩_∩)O哈哈~

    参考文献:
    https://www.cnblogs.com/zhuyeshen/p/11987696.html
    https://www.jianshu.com/p/742ce60e4c64

    附:foreach 参数及用法
    foreach元素的属性主要有item,index,collection,open,separator,close。

    • item:集合中元素迭代时的别名,该参数为必选。
    • index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选
    • open:foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选
    • separator:元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
    • close: foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
    • collection: 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键,Map对象没有默认的键。当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效

    相关文章

      网友评论

          本文标题:mybatis-plus 传参报错Type handler wa

          本文链接:https://www.haomeiwen.com/subject/vknuprtx.html