这个必须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的咩……