Mybatis如何傳遞多個參數——一個莫名空指針錯誤引起的思考


 

一、前言

今天在做一些高並發的簡單測試時(主要測試悲觀鎖、樂觀鎖、重入機制等等的效率,加深對鎖的理解),報了一個莫名其妙的空指針錯誤:

錯誤原因指向一個業務實現類:

 

觀察到,第62行只是一個簡單的判斷語句:

if(redPacket.getStock() > 0)

該判斷句所引對象來自61行代碼:

RedPacket redPacket = redPacketDAO.getRedPacket(redPacketId);

我發現,如果是空指針錯誤的話,那應該是對象redPacket為空,也就是說61行代碼執行失敗了。問題來了:既然61行執行失敗,干嘛要報62行的錯?果然,在我注釋掉62行及以后的代碼,print打印redPacket對象時,發現該對象本身及其所有屬性均能正常打印(自動該類調用自定義的toString()方法),並沒有報錯。

 

哈,到這里真的有點摸不着頭腦了,對象和他的屬性均正常,set.get方法也無誤,一個線程它正兒八經,正正常常的一行一行執行着,前一句不空,后一句突然變空,這…………

 

困難是有的,但還是可以解決的!抱着試一試的心態,先把62行外層if語句里所有內容注釋掉,嘗試性又執行一遍,額,空指針沒了。

以上就是發現這個奇葩空指針源頭的過程,再之后就簡單了,一句句排查,鎖定了錯誤的源頭在Mybatis的這個方法中:

 我注意到,sql語句中,參數有兩個:id和version,我卻還當作一個參數來處理:沒有定義parameterType。粗心的毛病啊,,,,當時這段是直接復制悲觀鎖的代碼,根本沒注意到多加了一個參數。

 

二、Mybatis如何傳遞多個參數

 

四種方法噢,咱由淺入深,先從最不常用的開始,哈哈。

(1)采用Map傳多參數

    Dao層:

public int selectUser(Map paramMap);

    Mapper.xml:

<update id="selectUser">
        update table_name
        set xxx
        where id = #{id}
        and version = #{version}
 </update>

    Service層:

Private User x(){
    Map paramMap=new hashMap();
    paramMap.put(“id”,”2”);
    paramMap.put(“version”,”1”);
    User user=xxx. selectUser(paramMap);
}

(2)使用#{arg0},#{arg1}...或#{param1},#{param2}

細心的小伙伴遇到類似錯誤時可能會發現錯誤日志里有類似的提醒:

Parameter ‘id’ not found. Available parameters are [arg1, arg0, param1, param2] 

沒錯,就是把sql代碼中#{id}和#{version}改為#{arg0}或者#{param1}等等:(注意:arg下標從0開始,param下標從1開始

    Dao層:

public int selectUser(Long id, int version);

    Mapper.xml:

<update id="selectUser">
        update table_name
        set xxx
        where id = #{arg0}
        and version = #{arg1}
 </update>

(3)定義一個實體類來承載多個參數

    pojo(實體類):

public class Param(){
private Long id; private int version; -------getter and setter------- }

    DAO層:

public int selectUser(Param p);

    Mapper.xml:同(1)

(4)使用@Param注解

    DAO層:

public int selectUser(@Param("id") Long id, @Param("version") int version);

    Mapper.xml同(1)

 

這四種方法中,個人認為第四種方法最好,使用@Param注解能讓開發者看到dao層方法就知道該傳什么樣的參數,比較直觀。

選擇上述四種方法任意一種,問題解決。

三、結語

與其說問題已經解決,不如說只是代碼不報錯了而已。留給我的問題是:為嘛參數傳遞格式有問題,會報空指針錯誤?為嘛對象正常,只有調用屬性的getter方法才會報錯?仍在思考,希望路過的大神指導一二。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM