這個必須mark,調試了整整前半夜……
因爲 mybatis的出現 就是自由書寫sql語句的,所以一貫的作用是把參數丟進Java的集合對象裏面傳進去,而且多半使用Map<String,Object>或者Map<String,String>,當碰見數據庫列是varchar字符串時就用#{} 框住map的key來取value,碰見Number(Oracle)時候就用${}來取。像這樣做做了一年都沒出什麼問題。今天照例這樣做……
說一下業務需要:建了一個成本對象表,表有個主鍵 SJXH,這個主鍵沒有用序列 sequence來生成,項目經理的要求是當要插入數據時,當前最大SJXH加1後insert進去。同事的做法是 先調用 mybatis selectOne api,然後將這個查出來的值set到此表對應的modle [CostStelyVo]或put到Map中去。 這個做法解決問題了,可我總感覺很彆扭:前後要調用兩次spring的session,中間還要put一次,嫌麻煩,而且不知道事務這塊spring會怎麼處理。
在網上查了mybatis的insert api。呵呵,發現了searchKey這個東東,有兩處用:第一處是針對自增長數據庫的,插入後返回插入數據的主鍵;第二處就是web系統自己插入數據的主鍵。很顯然第二種是符合目前情況的。
SJXH是主鍵,那顯然是Number型,自然而然就用${}來框住sjxh。很明顯就有了下面的代碼。
<insert id="insertCostStely" parameterType="java.util.map"
statementType="CALLABLE">
<selectKey keyProperty="sjxh" resultType="int" order="BEFORE">
select nvl(max(SJXH),0)+1 temp from cost_stely
</selectKey>
insert into cost_stely
(SJXH,XMBH ,DXDM ,MCDY ,BZ ,SFYX
)values
(${sjxh},#{xmbh},#{dxdm} ,#{mcdy},#{bz} ,${sfyx})
</insert>
有了S型的想法,B型的寫法,自然就有了SB型的代碼……
log出來:searchKey裏面的語句確實執行了,而且結果也是對的:134,但是 ${sjxh}對應的值仍然是0,也就是默認值。
坑爹……
然後新建了一個CostStely對應的VO,並將parameterType="java.util.map"換成parameterType="com.scitel.cs.xls.vo.CostStely",故障依舊。
反覆的debug……反覆的debug……反覆的debug……反覆的debug……
木有辦法了,把mybatis的官方文檔整出來研究《MyBatis-3-User-Guide.doc》。看到了裏面的寫法,跟上面差不多。
建VO、改xml、研究官網文檔,還是沒有下文。
然後試着將${sjxh}改成#{sjxh},junit start,咔咔,代碼運行OK……
--------------Ok的代碼---------------------
<insert id="insertCostStely" parameterType="com.scitel.cs.xls.vo.CostStely"
statementType="CALLABLE">
<selectKey keyProperty="sjxh" resultType="int" order="BEFORE">
select nvl(max(SJXH),0)+1 temp from cost_stely
</selectKey>
insert into cost_stely
(SJXH,XMBH ,DXDM ,MCDY ,BZ ,SFYX)
values
(#{sjxh},#{xmbh},#{dxdm} ,#{mcdy},#{bz} ,${sfyx}
)
</insert>
-------------------------------------------------或許大家以爲到此結束,其實木有哦
--------------------HLL的分割線--------------------------------------------------
將 【keyProperty="sjxh"】 改爲【keyProperty="SJXH"】以及將【 values(#{sjxh},】改爲【values(#{SJXH},】,代碼都將不能正常運行。前者在vo中找不到對應的set方法,後者在vo中找不到對應的get方法。坑爹的大小寫……
------------------------------
寫在這裏,告誡以後不要犯經驗主義錯誤:以前用的很好的習慣可能現在就是error的咩……