背景:有这么一个需求,需要保存主表基本信息,以商品为例,这个表就是商品表,但是随着后来业务发展,不同的商品会有不同的业务扩展属性,如果每当出现一个新的属性我们就给商品主表加字段,那么这个主表后来就会变得非常臃肿,并且字段得不到有效利用(毕竟不是每种商品都有这个属性),于是我们想到了创建一个纵向商品属性表(good_id,name,value),即每加入一个属性就插入商品id,属性名,属性值,这样就满足了商品基本属性和扩展属性的保存,且有效利用了数据表空间。但是当我们保存数据的时候问题出现了,我们要分别保存基本属性(商品表)和扩展属性(扩展纵表),基本属性表很容易保存,那么扩展属性呢?以mybatis为例,我们传入一个map对象,map中的键值对就是我们要保存的商品扩展属性[{good_id=1},{attribute1=xx},{attribute2=yy}...].于是我们在mabitis的mapper中写下这么一段:
<insert id="saveChannelDetail" parameterType="map" >
INSERT INTO t_channel_detail_info (channel_id,name,value) VALUES
<foreach collection="parameter" index="key" item="value" >
<if test="key=='appid'">
(
#{channel_id},
#{key},
#{value}
)
</if>
</foreach>
</insert>
结果是:
Caused by: org.apache.ibatis.builder.BuilderException: The expression 'parameter' evaluated to a null value.
尝试将mybatis的java接口参数作为名字,我的是params,但是仍然出错。debug发现,其实xml中接收的是经过mybatis处理过的_parameter参数,带下划线的参数名。
试了下,果然解决!
批量更新也是一样的:
<update id="editChannel">
<foreach collection="_parameter" index="key" item="value" separator=";">
<if test="key=='appid' || key=='sourType' || key=='gdFlag'
|| key=='cqFlag' || key=='appKey' || key=='secret'
|| key=='ecCode' || key=='password' || key=='serinum'
|| key=='smsCode' || key=='companyCode' || key=='busiCode'
|| key=='netUser' || key=='netPassword' || key=='dxUserid'
|| key=='dxPassword' || key=='dxKey' || key=='hzUserid'
|| key=='hzPassword' || key=='maiGuUserId' || key=='maiGuKey'
|| key=='zhongtianAppKey' || key=='zhongtianSecret' ">
update t_channel_detail_info set value = #{value,jdbcType=VARCHAR} where channel_id=#{channelId} and name = #{key}
</if>
</foreach>
</update>