mybatis-plus 傳參報(bào)錯(cuò)Type handler was null on parameter mapping for property '__frch_value_0'.

報(bào)錯(cuò)日志:

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進(jìn)行查詢操作,按照公司規(guī)范化封裝方式性傳參,一直報(bào)錯(cuò)?。z查傳參類型、參數(shù)名稱都無(wú)誤【o(╥﹏╥)o】

  • 實(shí)現(xiàn)類
       // IWrapper  參數(shù)是list查詢時(shí),需要封裝兩層
   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);

原因:傳參個(gè)數(shù)造成的,需要改變參數(shù)傳入構(gòu)造方式

  • 改變實(shí)現(xiàn)類
    // IWrapper 單層參數(shù)
   public List<IWrapper> list(IWrapper wrapper, String dealStatus) {
        return alarmEventMapper.list(wrapper), dealStatus);
    }

程序訪問(wèn)沒(méi)有問(wèn)題了。。。Why?頭疼o(╥﹏╥)o
后來(lái)去看了下調(diào)用源碼發(fā)現(xiàn),mybatis在參數(shù)大于一個(gè)時(shí),會(huì)再次封裝參數(shù)為Map!
源碼如下:【重點(diǎn)在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源碼調(diào)流程:


image.png

mybatis在使用Mapper進(jìn)行編程時(shí),其實(shí)際是通過(guò)MybatisMapperProxy代理機(jī)制,調(diào)用的SqlSession對(duì)應(yīng)方法(例如:selectOne(),selectList()),會(huì)把參數(shù)進(jìn)行校驗(yàn)和重新封裝,導(dǎo)致sql執(zhí)行中參數(shù)不一致報(bào)錯(cuò)!
就這么無(wú)厘頭的解決了,O(∩_∩)O哈哈~

參考文獻(xiàn):
https://www.cnblogs.com/zhuyeshen/p/11987696.html
http://www.itdecent.cn/p/742ce60e4c64

附:foreach 參數(shù)及用法
foreach元素的屬性主要有item,index,collection,open,separator,close。

  • item:集合中元素迭代時(shí)的別名,該參數(shù)為必選。
  • index:在list和數(shù)組中,index是元素的序號(hào),在map中,index是元素的key,該參數(shù)可選
  • open:foreach代碼的開(kāi)始符號(hào),一般是(和close=")"合用。常用在in(),values()時(shí)。該參數(shù)可選
  • separator:元素之間的分隔符,例如在in()的時(shí)候,separator=","會(huì)自動(dòng)在元素中間用“,“隔開(kāi),避免手動(dòng)輸入逗號(hào)導(dǎo)致sql錯(cuò)誤,如in(1,2,)這樣。該參數(shù)可選。
  • close: foreach代碼的關(guān)閉符號(hào),一般是)和open="("合用。常用在in(),values()時(shí)。該參數(shù)可選。
  • collection: 要做foreach的對(duì)象,作為入?yún)r(shí),List對(duì)象默認(rèn)用"list"代替作為鍵,數(shù)組對(duì)象有"array"代替作為鍵,Map對(duì)象沒(méi)有默認(rèn)的鍵。當(dāng)然在作為入?yún)r(shí)可以使用@Param("keyName")來(lái)設(shè)置鍵,設(shè)置keyName后,list,array將會(huì)失效
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容