MyBatis批量添加、更新、删除实战篇(日常开发必看)

前言

工作中,经常会遇到很多批量操作的需求:批量添加、批量更新、批量删除、批量导入、批量审核等等,下面这篇文章我们将一一复现,首先我们先了解一下mybatis的标签foreach循环:

一、MybatIs标签foreach

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。

foreach元素的属性主要有 item,index,collection,open,separator,close。

1》item集合中每一个元素进行迭代时的别名

2》index表示在迭代过程中,每次迭代到的位置

3》open该语句以什么开始

4》separator在每次进行迭代之间以什么符号作为分隔符

5》close以什么结束

1.collection属性主要有一下3种情况:

1.1 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list

1.2 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

1.3 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了

二、批量添加

当传入参数是list集合的时候:

2.1 Mapper.xml

<!--批量插入员工数据-->
<insert id="saveEmp" parameterType="java.util.List">
    INSERT INTO t_employee(id, name, age, salary, department_id,update_time)
    VALUES
    <foreach collection="list" item="item" index="index" separator=",">
        (#{item.id},#{item.name},#{item.age},#{item.salary},#{item.departmentId},now())
    </foreach>
</insert>

2.2 Controller层

@PostMapping("saveBath")
@ResponseBody
public CommonResult<Employee> saveBath(@RequestBody List<Employee> employeeList){
    return employeeService.saveEmp(employeeList);
}

@ResponseBody:返回Json数据 @RequestBody:接受Json数据

2.3 Json数组集合数据

[
    {
    "id": 1,
    "name": "DT测试1",
    "age": 26,
    "salary": 10000.0,
    "departmentId": 1
    },
    {
    "id": 2,
    "name": "DT测试2",
    "age": 26,
    "salary": 10000.0,
    "departmentId": 2
    }
]

三、批量更新

1.Mapper.xml

1.1 批量更新第一种方法

<update id="updateBatch" parameterType="java.util.List" >
    <foreach collection="list" item="item" index="index" separator=";">
        UPDATE t_employee
        <set>
            <if test="item.name != null and item.name != ''" >
                name = #{item.name},
            </if>
            <if test="item.age != null" >
                age = #{item.age},
            </if>
            <if test="item.salary != null" >
                salary = #{item.salary},
            </if>
            <if test="item.salary != null" >
                salary = #{item.departmentId},
            </if>
        </set>
        where id = #{item.id}
    </foreach>
</update>

记得连接数据库加:

allowMultiQueries=true

不然会报如下错误:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE t_employee

MySQL连接数据库时,添加语句:“allowMultiQueries=true”的作用:

1.可以在sql语句后携带分号,实现多语句执行。 2.可以执行批处理,同时发出多个SQL语句。

这种方式就是通过SQL拼接,单条单条地进行更新。

1.2 批量更新第二种方法

<update id="updateBatch" parameterType="java.util.List" >
    update t_employee
    <trim prefix="set" suffixOverrides=",">
        <trim prefix="name=case" suffix="end,">
            <foreach collection="list" item="i" index="index">
                <if test="i.name != null and i.name != ''">
                    when id=#{i.id} then #{i.name}
                </if>
            </foreach>
        </trim>
        <trim prefix="age=case" suffix="end,">
            <foreach collection="list" item="i" index="index">
                <if test="i.age != null">
                    when id=#{i.id} then #{i.age}
                </if>
            </foreach>
        </trim>
    </trim>
    where
    <foreach collection="list" separator="or" item="i" index="index" >
        id = #{i.id}
    </foreach>
</update>

实际上是通过case when语句进行批量更新,只要一条SQL语句:

MyBatis批量添加、更新、删除实战篇(日常开发必看)

当然除了上面两种方式外,还可通过如下:

批量更新第三种方法,用ON DUPLICATE KEY UPDATE,就是一个批量插入操作,在插入的时候,如果已存在,则更新,所以可以变相达到批量修改的效果。

一般不推荐这种更新大数据量的SQL,关于这种方式小编前面的文章也有说过使用方式,这里不再赘述。

注意:上面的方式是针对多个字段的情况,如果只是更新单个字段,可以这么写:

<!-- 批量更新第二种方法,针对单个字段进行批量更新 -->
<update id="updateBatch" parameterType="java.util.List">
    UPDATE t_employee
    SET name = CASE
    <foreach collection="list" item="item" index="index">
        WHEN id = #{item.id} THEN #{item.name}
    </foreach>
    END
    WHERE id IN
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
        #{item.id}
    </foreach>
</update>

2.Controller层

 @PostMapping("updateBatch")
 @ResponseBody
 public CommonResult<Employee> updateBatch(@RequestBody List<Employee> employeeList){
     return employeeService.updateBatch(employeeList);
 }

3.Json集合数据

[
    {
    "id": 1,
    "name": "DT测试111",
    "age": 2611
    },
    {
    "id": 2,
    "name": "DT测试211",
    "age": 2611
    }
]

四、批量删除

1. 传入的是List数组对象

1.Mapper.xml

<delete id="deleteBath" parameterType="java.util.List">
   DELETE FROM t_employee WHERE id IN
    <foreach collection="list" item="item" open="(" separator="," close=")">
        #{item.id}
    </foreach>
</delete>

2.Controller层

@PostMapping("deleteBath")
@ResponseBody
 public CommonResult<Employee> deleteBath(@RequestBody List<Employee> employeeList){
     return employeeService.deleteBath(employeeList);
 }

3.Json集合数据

[
    {
    "id": 1
    },
    {
    "id": 2
    }
]

2. 传入的是数组

1.Mapper.xml

<delete id="deleteBath" parameterType="java.util.Arrays">
    DELETE FROM t_employee WHERE id IN
    <foreach collection="array" item="ids" open="(" separator="," close=")">
        #{ids}
    </foreach>
</delete>

2.Controller层

@PostMapping("deleteBath")
@ResponseBody
public CommonResult<Employee> deleteBath(@RequestBody int[] ids){
    return employeeService.deleteBath(ids);
}

3.Json数组

[1,2]

2. 传入的是Map集合

1.Mapper.xml

<delete id="deleteBath" parameterType="java.util.Map">
    DELETE FROM t_employee WHERE id IN
    <foreach collection="ids" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</delete>
int deleteBath(@Param("ids") Map<String, Integer> ids);

2.Controller层

 @PostMapping("deleteBath")
 @ResponseBody
 public CommonResult<Employee> deleteBath(@RequestBody Map<String,Object> map){
     // 接收List
     List<Integer> ids = (List<Integer>) map.get("ids");
     Map<String, Integer> stringMap = new HashMap<>();
     ids.forEach(id -> stringMap.put("ids", id));
     return employeeService.deleteBath(stringMap);
 }

3.map数据

{
    "ids": [1,2]
}

五、批量查询

1.Mapper.xml

<select id="findBath" resultType="com.dt.springbootdemo.entity.Employee" parameterType="com.dt.springbootdemo.entity.Employee">
    SELECT * FROM t_employee WHERE id IN
    <foreach collection="list" item="item" open="(" separator="," close=")">
        #{item.id}
    </foreach>
</select>

2.Controller层

@GetMapping("findBath")
@ResponseBody
public CommonResult<List<Employee>> findBath(@RequestBody List<Employee> employeeList){
    return employeeService.findBath(employeeList);
}

3.Json集合数据

[
    {
    "id": 1
    },
    {
    "id": 2
    }
]

至于其它的数据格式就不再赘述了,很简单,变一下数据格式就可以了:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容