mybatis Invalid bound statement(not found)排坑記錄
背景
之前幫同事解決mybatis Invalid bound statement (not found):這個問題,最近看到很多人也遇到這樣的問題,所以就記錄一下出現(xiàn)這種情況的幾種情況。
問題分析
出現(xiàn) Invalid bound statement (not found) 這個錯誤的原因:
是根據(jù) mapper接口的全路徑 以"."(點(diǎn)號)與方法名拼接成字符串,作為唯一key(下面將以key代替 ) 到 Map<String, MappedStatement> mappedStatements (后續(xù)已map 代替該對象)中去獲取對應(yīng)的MappedStatement, 如果獲取不到就報(bào)這個錯誤。
根據(jù)上面的流程,也就解釋了為什么mapper 中的方法不能重載的原因。因?yàn)楂@取MappedStatement 是根類和方法名有關(guān),與參數(shù)無關(guān)。所以不能重載。
繼續(xù)分析Invalid bound statement 這個錯誤,出現(xiàn)這個錯誤是因?yàn)楂@取不到MappedStatement,也就是說在map 容器中根據(jù)key 去獲取值,沒有獲取到。
解決
那么問題來了,什么情況下在map中根據(jù)key 獲取不到值呢?
其實(shí)獲取不到就兩種情況。
- 第一種情況: 就是map 是一個空集合。
- 第二種情況:map中沒有這個key (也就是說key值不對)
什么情況下mappedStatements 這個map 為空呢?
回答這個問題要明白mybatis 的原理。
在項(xiàng)目啟動的過程中,會掃描并解析掃描到的mapper.xml 文件,將xml文件的namespace 與select 、update 、insert、delete 標(biāo)簽的id 以 namespace.id 的形式組成一個唯一的key ,將sql語句封裝成一個MappedStatement 對象作為value存儲在mappedStatements 這個map 集合中。
所以當(dāng)map集合為空,說明mapper.xml 沒有被容器掃描到。
那什么情況下項(xiàng)目中有mapper.xml 文件卻沒有被掃描到呢?
回答這個問題,要清楚mybatis mapper.xml 文件的加載目錄。
當(dāng)我們沒有在配置文件中配置指定目錄或者配置配置錯誤的文件地址。
mybatis: mapper-locations: classpath:mybatis/mapper/*.xml
在容器啟動的時(shí)候會到配置文件指定的目錄和mapper 接口所在的包中查找,如果查找不到map集合就是空的。
這時(shí)候有的人該問
配置文件配置的mapper.xml 文件地址沒有錯誤,為什么map 還是空的?
如果出現(xiàn)這個問題,我們需要排查一下target 目錄中是否有mapper.xml 文件 因?yàn)閙aven 編譯打包 會將代碼編譯打包成target文件中,程序運(yùn)行也是讀取加載該目錄下的文件,而不是我們項(xiàng)目目錄。
這時(shí)需要在pom 文件build中添加如下配置
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.yml</include> </includes> <filtering>false</filtering> </resource> </resources>`
map為空總結(jié)
1、 檢查mapper的xml文件 是否在mapper 接口包中。如果不在,說明指定了目錄(目前一般都是在resource 資源目錄下新建文件夾) 如果指定了目錄 需要在配置文件中配置指定的目錄。
注意:在resource 目錄下創(chuàng)建多級目錄時(shí),要一層一層創(chuàng)建,不要像創(chuàng)建Java目錄一下以"."隔開,這樣是不對的。
2、項(xiàng)目配置沒有問題,還出現(xiàn)這個問題,排查一下target 目錄中是否有mapper.xml 。沒有則說明maven 打包的時(shí)候沒有將xml 文件打包進(jìn)jar中,需要在pom中添加resource配置信息。
下面來說說第二種情況:key 值不正確
1、這種情況 需要排查mapper 接口全路徑 與 mapper xml 文件中的namespace 配置是否一致。
這里有個驗(yàn)證技巧:
按住Ctrl 鍵 鼠標(biāo)點(diǎn)擊接口名 看看是否能正常跳轉(zhuǎn)到接口中,如果能正常跳轉(zhuǎn),則說明映射成功,如果不能跳轉(zhuǎn),則說明namespace 配置的不正確,需要修改。
2、隱射成功,下一步拷貝接口中的方法名 到xml 文件中查找是否有對應(yīng)的sql,排查xml sql 的id值是否與方法名一致。(注意空格)
這里也有一個排錯技巧:
在idea 上安裝 Free Mybatis plugin插件,這樣 按住Ctrl 鍵 點(diǎn)擊id 看是否能跳轉(zhuǎn)到接口中對應(yīng)的方法上。如果不能則說明id 的值不對,修改成方法名即可。
看到這里估計(jì)有人又該問了
我怎么知道m(xù)ap中是否為空呢?怎么知道key是不正確呢?
如果有看源碼能力的,可以debug項(xiàng)目 追源碼。
如果不想看源碼的,我這里給一個很直接的方式。debug模式啟動項(xiàng)目后,記住是在項(xiàng)目啟動后,在mybatis 源碼中打斷點(diǎn),然后請求 debug查看。
千萬別在啟動項(xiàng)目前打斷點(diǎn),因?yàn)轫?xiàng)目啟動加載也會走這里,這樣會看迷糊的。記住是啟動項(xiàng)目后,訪問前 打斷點(diǎn)
總結(jié)
這是我目前能找到錯誤的原因和解決的方式方法。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
- 解決mybatis plus報(bào)錯Invalid bound statement (not found):問題
- 解決java中mybatis報(bào)錯:org.apache.ibatis.binding.BindingException:Invalid bound statement(not found):xx問題
- SpringBoot報(bào)錯Invalid?bound?statement?(not?found)問題排查和解決方案
- mybatis整合springboot報(bào)BindingException:Invalid?bound?statement?(not?found)異常解決
- Invalid bound statement(not found):錯誤的解決方案
相關(guān)文章
@CacheEvict + redis實(shí)現(xiàn)批量刪除緩存
這篇文章主要介紹了@CacheEvict + redis實(shí)現(xiàn)批量刪除緩存方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10全面匯總SpringBoot和SpringClould常用注解
Java注解是附加在代碼中的一些元信息,用于一些工具在編譯、運(yùn)行時(shí)進(jìn)行解析和使用,起到說明、配置的功能,這篇文章就帶你來了解一下2021-08-08java8實(shí)現(xiàn)List中對象屬性的去重方法
這篇文章主要介紹了java8實(shí)現(xiàn)List中對象屬性的去重方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03使用Runnable實(shí)現(xiàn)數(shù)據(jù)共享
這篇文章主要為大家詳細(xì)介紹了如何使用Runnable實(shí)現(xiàn)數(shù)據(jù)共享,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Java8函數(shù)式編程應(yīng)用小結(jié)
Java8非常重要的就是引入了函數(shù)式編程的思想,使得這門經(jīng)典的面向?qū)ο笳Z言有了函數(shù)式的編程方式,彌補(bǔ)了很大程度上的不足,函數(shù)式思想在處理復(fù)雜問題上有著更為令人稱贊的特性,本文給大家介紹Java8函數(shù)式編程應(yīng)用小結(jié),感興趣的朋友一起看看吧2023-12-12Jetty啟動項(xiàng)目中引用json-lib相關(guān)類庫報(bào)錯ClassNotFound的解決方案
今天小編就為大家分享一篇關(guān)于Jetty啟動項(xiàng)目中引用json-lib相關(guān)類庫報(bào)錯ClassNotFound的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12