学前小课堂:
<!-- 引入sql片段 refid :被引入sql片段的id-->
<include refid="condition_sql_by_trim"/>
<!-- 动态SQL语句trim标签
perfix : 动态sql语句的前缀 (WHERE,SET)
prefixOverrides : 自动截取掉或者替换条(WHERE 多余后面 关键字 :AND-OR)
-->
<!-- 动态sql语句 foreach 循环标签
<foreach collection="" open="" close="" item="" separator=""></foreach>
collection : 要循环集合或者数组
open :开始位置符号 前小括号 (
close : 开始位置符号 后小括号 )
item : 每次循环的数据
separator : 分隔符 逗号 ,
-->
<!--判断-->
<if test="name !=null"> name = #{name},</if>
一、批量删除
<!-- 批量删除 --> <delete id="deleteByIds" parameterType="list"> <!-- delete from user where id in (1,3,5,56,8) --> delete from user where id in <!-- 动态sql语句 foreach 循环标签 <foreach collection="" open="" close="" item="" separator=""></foreach> collection : 要循环集合或者数组 open :开始位置符号 前小括号 ( close : 开始位置符号 后小括号 ) item : 每次循环的数据 separator : 分隔符 逗号 , --> <foreach collection="ids" open="(" close=")" item="id" separator=","> #{id} </foreach> </delete>
二、批量插入
<!-- 批量插入 --> <insert id="batchInsert" parameterType="list"> <!-- insert into user (name,password,age) values (xxx,x,xx),(xxx1,x1,xx1),(xxx2,x2,xx2) --> insert into user (name,password,age) values <!-- 动态sql语句 foreach 循环标签 --> <foreach collection="users" separator="," item="user"> (#{user.name},#{user.password},#{user.age}) </foreach> </insert>
三、批量更新
批量更新的写法一般有三种,在更新数量较少的情况下,前两种性能不相上下。但是在更新字段增加,更新条数较多(500以上)建议使用第三种写法。
- 常规写法,拼接多个单条更新语句。
CASE...WHEN...
写法JOIN
写法
①Batch Update
spring/mybatis/JDBI都支持这种批量更新方式。
这种更新方式需要设置jdbc连接的参数:
allowMultiQueries=true # 完整url举例 jdbc.url=jdbc:mysql://localhost:3306/db_name?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
具体实现以Spring的JdbcTemplate
为例。batchUpdate
的主要代码如下图:
②CASE WHEN
<update id="updateBatch" parameterType="java.util.List"> update mydata_table <trim prefix="set" suffixOverrides=","> <trim prefix="status =case" suffix="end,"> <foreach collection="list" item="item" index="index"> when id=#{item.id} then #{item.status} </foreach> </trim> </trim> where id in <foreach collection="list" index="index" item="item" separator="," open="(" close=")"> #{item.id,jdbcType=BIGINT} </foreach>
结构如下:
update mydata_table
set status =
case
when id = #{item.id} then #{item.status}//此处应该是<foreach>展开值
...
end
where id in (...);
UPDATE test SET code = ( CASE WHEN id = 1 THEN 11 WHEN id = 2 THEN 22 WHEN id = 3 THEN 33 END ) WHERE id IN (1,2,3);
注意:CASE WHEN
一定要和WHERE
语句一起使用,否则UPDATE会遍历和更新数据库中所有的行。会把未出现在WHEN
中的数据都更新成null
,如果code
列设置为NOT NULL
则会报错,否则会置为NULL或者默认值
三、JOIN
UPDATE `test` a JOIN ( SELECT 1 AS id, 11 AS code, 'holy' AS name UNION SELECT 2 AS id, 22 AS code, 'shit' AS name ) b USING(id, code) SET a.name=b.name;
上述SQL要表达的更新语义是:将id=1且code=11的name更新为'holy',将id=2且code=22的name更新为'shit'。
注意,条件字段必须放在USING
中