mybatis 使用小总结
动态更改表名
不能直接用#{value}
,要使用${value}
,同时在mapper中方法的参数前加上@Param("value")
,注意mapper中指定的名称要和xml文件中一致。
#{}与${}的区别
个人理解,#
就是占位符,而$
是字符串拼接。
就拿上面的改表名来说,你用#{value}
的话会替换成'value'
,而${value}
会替换成valve
,注意,不是没区别,后者没带引号,所以可以作为表名。
如果你想要传多个字符串,而又不想用map
,我的解决方案是方法参数列表用@Param("key")String key
,取值的时候用${key}
,注意如果key
是字符串,最好手动加引号'${key}'
执行多个sql语句
使用mybatis连postgresql,是可以直接运行多个sql语句的,如在一个<delete></delete>
标签中删除多个表,中间用分号隔开就行了。
后来在mysql里面跑多个sql,直接就挂了。解决方式也很简单,在mysql连接url后面加一个allowMultiQueries=true
其实数据库连接url后面有很多好东西可以加,如zeroDateTimeBehavior=convertToNull
,这样如果时间类型为空,就不会抛什么null值无法转换成Date类型异常。
多个参数
例如,想要传两个字符串类型的为参数,在mapper.xml中就要使用#{arg0}
和#{arg1}
获取,当然,如果你的版本比较老,可以用#{0}
和#{1}
,其实,有时候会告知你要用#{param0}
和#{param1}
。你要问我具体用什么,我会告诉你,我也不知道,看报错提示咯。
友情提示,如果你传递的多个参数类型不同,这时候不必写parameterType
,否则你在xml指定String,传递Integer时会抛类型转换异常。
批量插入
mapper.xml
<insert id="insertBatch" parameterType="java.util.List">
insert into track (latitude, longitude,time) values
<foreach collection="list" separator="," item="track">
(#{track.latitude,jdbcType=DOUBLE},
#{track.longitude,jdbcType=DOUBLE},
#{track.time,jdbcType=TIMESTAMP})
</foreach>
</insert>
mapper interface
int insertBatch(@Param("list") List<Track> list);
属性值为空时,不插入对应的字段
mapper.xml
<insert id="insertBatch" parameterType="java.util.List">
<foreach collection="list" item="track" separator=";">
insert into track
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="#{track.latitude} !=null">latitude,</if>
<if test="#{track.longitude} !=null">longitude,</if>
<if test="#{track.time} !=null">time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="#{device.operationType} !=null">#{device.operationType},</if>
<if test="#{track.latitude} !=null">#{track.latitude},</if>
<if test="#{track.longitude} !=null">#{track.longitude},</if>
<if test="#{track.time} !=null">#{track.time},</if>
</trim>
</foreach>
</insert>
mapper interface
int insertBatch(List<Track> list);
可以看到,上面两种是采用了不同的方式,一种是指定多个值,一种是执行多次插入,都可以实现给一张表插入多条记录的操作。
批量修改
mapper.xml
<update id="updateBoundsByLayers" parameterType="java.util.List">
<foreach collection="list" separator=";" item="map">
update track set time = #{map.time} where id= #{map.id}
</foreach>
</update>
mapper interface
void updateTrackBatch(List<Map<String, String>> list);
返回结果
- 批量插入:返回插入记录的个数
- 批量修改:返回修改记录的个数
- 删除:返回删除记录的个数
- 多条sql:返回最先执行的sql作用的结果数,也就是以最上面那一条为准
- 插入返回主键:使用
<insert useGeneratedKeys="true" keyProperty="id" keyColumn="id"
,keyColumn
可以不要,mybatis会自动取到主键,然后将值赋给你插入时使用的对象,批量插入时也适用。