com.baomidou.mybatisplus在XML中寫insert/update的時候要注意有沒有parameter

事情是這樣的,最近在重構舊項目,項目中有一段邏輯調用了Oracle的存儲過程,類似於這樣:

這段存儲過程的SQL是在數據庫裏面的,非常長,我是很不喜歡在程序中使用存儲過程的,這些邏輯也可以放在程序中啊。看不過眼就把這段長長的SQL複製到XML中了, 就成了這樣:

這是insert,還有update:

太長了還用了begin/end就都截圖了一部分 。可以看出來這段存儲過程執行的時候是不需要任何參數的,所以這裏<update>和<insert>標籤頁沒有寫parameterType,當然mapper中對應的方法頁沒有傳任何參數,就想這樣:

想着這樣應該沒有問題了,一執行卻報錯了,看了一眼異常棧信息:

通過異常棧信息可以看出來是報了空指針,而且可以看出來項目中用了mybatis-plus, 定位到了拋出異常的方法MybatisDefaultParameterHandler.processBatch(),看一下這個方法:

這是一個自動填充主鍵ID的一個方法,這對Orcale是很實用的 ,因爲Oracle是不可以設置主鍵自增,而MybatisPlus提供繼承MetaObjectHandler類的這種方法去自動填充主鍵,具體怎麼操作後面會說,先說這次的問題出在哪裏。

現在有insert類型的SQL,而且都是沒有任何參數的,所以這裏isFill=true,由於沒有參數,parameterObject就成了null,於是getParameters(parameterObject)返回的就是null,即parameters爲null,不滿足null!=parameters的條件走了下面的else分支,但是這時候parameterObject也是null啊,所以這裏的parameterObject.getClass()就報了空指針NullPointerException異常。update類型的SQL也是同理,不過好在update類型的SQL還有一個條件判斷即metaObjectHandler.openUpdateFill(),可以把這個理解成一個開關,還可以控制update類型的SQL是不是需要自動填充,只要isFull爲false也不會有什麼問題,這個開關也是通過繼承MetaObjectHandler類來控制,待會和如何自定義主鍵自增一起說。

然後這裏的insert類型的SQL就沒有這種開關控制了,MybatisPlus有很多jar包,這個項目中用的是com.baomidou.mybatisplus,也就是說在這個裏面,只要是insert類型的SQL沒有任何參數,就比如我遇到的這個場景,這裏就會空指針,太現實了叭。

然後說一下如何通過繼承MetaObjectHandler類來控制update類型的SQL是否自動填充的開關和自定義填充主鍵的方法,很簡單如圖:

就是繼承MetaObjectHandler分別重寫insertFill方法自定義主鍵填充邏輯,重寫openUpdateFill方法控制update類型的SQL是否自動填充,這個MetaObjectHandler中還有其他方法比如updateFill()等可以去了解一下。

最後說一下我是怎麼解決今天遇到的問題的,對於update類型的SQL就是重寫了這個openUpdateFill()方法,這就不說了,有意思的是對於insert類型的SQL,我給它強行加了一個參數,雖然SQL執行的時候並不需要.......如圖:

 

雖然有點蠢,不過問題解決了,就這樣吧。 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章