MyBatis批量增删改查

1. 为什么使用单个语句进行批量增删改查操作?

在MyBatis中,批量操作数据时,直接在for循环中逐条执行SQL语句与使用单个语句进行批量操作有显著区别,主要体现在性能资源消耗执行效率上:

性能与效率

  • 逐条操作:如果在服务层(如Java的Service类中)使用for循环,对每条数据都单独执行一次SQL操作,这意味着每次操作都会涉及数据库连接的建立SQL语句的发送执行结果处理,随后关闭连接。这种方式会导致大量重复的数据库交互,极大地增加了网络IO负担和数据库负载,性能低下。
  • 批量操作:相比之下,使用MyBatis的<foreach>标签或者直接在SQL中利用IN语句等方式进行批量操作,可以在一次数据库交互中处理多条数据。这样可以显著减少数据库连接的建立和释放次数,降低网络通信成本,提高执行效率。

资源消耗

  • 逐条操作:由于每次操作都需要一个新的数据库连接,因此资源消耗较大,尤其是在高并发场景下,可能会迅速耗尽数据库连接池资源。
  • 批量操作:批量操作通过一次性处理多条记录,减少了数据库连接的需求,从而降低了资源消耗,有助于保持系统稳定性。

事务管理

  • 逐条操作:如果需要事务支持,每次操作都可能需要单独管理事务,这可能导致事务开销增大,并且在出现错误时回滚策略复杂。
  • 批量操作:批量操作可以在一个事务中完成,简化了事务管理,提高了数据一致性。一旦发生错误,可以整体回滚,保证数据的完整性。

数据安全性与一致性

  • 批量操作虽然高效,但在处理大量数据时需谨慎,因为一旦发生错误,可能影响到整个批次的数据,而不是单条数据。逐条操作在这方面更为安全,但牺牲了效率。

2. <foreach> 标签

2.1. 简介

MyBatis中的<foreach>标签主要用于在动态SQL中迭代集合,实现批量操作或者构建含有多个变量的IN条件语句等功能。

2.2. 基本语法与属性

<foreach collection="collectionExpression" item="itemAlias" index="index" open="startString" close="endString" separator="separatorString">
  SQL片段
</foreach>
  • collection="collectionExpression":指定要遍历的集合对象的表达式,例如:listarray等。
  • item="itemAlias":表示集合中每一个元素的别名,用于在<foreach>内部引用当前遍历的元素。
  • index="index"(可选):在集合或数组迭代时,当前索引值将被赋值给index变量,可以在SQL语句中使用${index}来引用它。
  • open="startString"(可选):在遍历结果之前添加的字符串,通常用于SQL的开始部分,比如(
  • close="endString"(可选):在遍历结果之后添加的字符串,通常用于SQL的结束部分,比如)
  • separator="separatorString"(可选):分隔符,用于分隔每个遍历元素产生的SQL片段,默认是逗号,

2.3. 示例

2.3.1. 传入含有指定分割符的字符串String

<!-- 传入String devices="1,2,3,4,5" -->

<!-- 使用split(',')将其转换为List, item="devcie"指定分割后的元素别名 -->
<foreach collection="devices.split(',')" item="device" >
  #{device}
</foreach>

2.3.2. 传入数组T[]

<!-- 传入String[] devices={"1", "2", "3", "4", "5"} -->

<!-- List可以直接遍历 -->
<foreach collection="devices" item="device" >
  #{device}
</foreach>

2.3.3. 传入Map或实体类中包含列表或指定分割符的字符串String

<!--
    Map<T,T> map = {
                      "ids": [1,2],
                      "devices":"1,2,3,4,5"
                    } 
-->

<select>
  <foreach collection="devices.split(',')" item="device" >
    #{device}
  </foreach>
  
  <foreach collection="ids" item="id" >
    #{id}
  </foreach>
</select>

2.3.4. 传入列表List<基本类型>

<!-- List<String> devices = Arrays.asList("1", "2", "3", "4", "5"); -->

<!-- List可以直接遍历 -->
<foreach collection="devices" item="device" >
  #{device}
</foreach>

2.3.5. 传入列表List<Map或实体类>

<!-- 
    此处便于理解写成JSON格式
    List<Map<T,T>> deviceList = [{
                                   "id": 1,
                                   "name":"一号设备"
                                 },{
                                   "id": 2,
                                   "name":"二号设备"
                                 },{
                                   "id": 3,
                                   "name":"三号设备"
                                }]
-->

<update id="updateByListMaps" parameterType="java.util.List">
    <foreach collection="deviceList" item="deviceMap" separator=";">
        UPDATE table_name
        SET column_name = #{deviceMap.name}
        WHERE id = #{deviceMap.id}
    </foreach>
</update>

3. 批量插入

<!-- 
// Dao层java代码
Integer addRecordList(List<Record> crList);
-->

<insert id="addRecordList"> 
  INSERT INTO 
    record(id, code, state, start_time, create_time) 
  VALUES
  <foreach collection="crList" separator=", "item="item">
    (#{item.id},#{item.code},#{item.state},#{item.start_time},#{item.create_time}) 
  </foreach>
</insert>

4. 批量删除

<!-- 
// Dao层java代码
Integer delChannelInfoByIds(String ids);
-->

<delete id="delChannelInfoByIds">
  delete from 
    channel
  where id in
  <foreach collection="ids.split(',')" item="id" open="(" close=")" separator=","> 
    #{id}
  </foreach>
</delete> 

5. 批量更新

<!-- 
// Dao层java代码
Integer updateChannelById(List<Map<String,Object>> updateList);
-->

<update id="updateChannelById">
  <foreach collection="updateList" item="item" separator=";">
    update 
      channel 
    set 
      number=#{item.channelNumber},
      name=#{item.channelName}
    where
      id=#{item.deviceId} 
  </foreach>
</update> 

6. 批量查询

<!-- 
// Dao层java代码
List<Point> queryPointByIds(String ids);
-->

<select id="queryPointByIds" resultMap="BaseResultMap"> 
  select 
    i.* 
  from 
    point i
  where 
    i.id in
    <foreach item="item" collection="ids" open="(" separator=", close=")"> 
      #{item}
    </foreach>
</select> 
  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过使用 MyBatis 的 `batch` 操作来实现批量增删改查。 首先,需要在 Mapper 中定义对应的方法,如下所示: ```java public interface UserMapper { void insertUsers(@Param("users") List<User> users); void updateUsers(@Param("users") List<User> users); void deleteUsers(@Param("ids") List<Integer> ids); List<User> selectUsers(@Param("ids") List<Integer> ids); } ``` 然后,在 Mapper.xml 文件中实现对应的 SQL 语句,如下所示: ```xml <insert id="insertUsers" parameterType="java.util.List"> insert into user (id, name, age) values <foreach collection="users" item="user" separator=","> (#{user.id}, #{user.name}, #{user.age}) </foreach> </insert> <update id="updateUsers" parameterType="java.util.List"> <foreach collection="users" item="user" separator=";"> update user set name=#{user.name}, age=#{user.age} where id=#{user.id} </foreach> </update> <delete id="deleteUsers" parameterType="java.util.List"> delete from user where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </delete> <select id="selectUsers" parameterType="java.util.List" resultMap="userResultMap"> select * from user where id in <foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach> </select> ``` 接下来,在 Java 代码中调用对应的方法,如下所示: ```java SqlSession sqlSession = sqlSessionFactory.openSession(); try { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 批量插入用户 List<User> users = new ArrayList<>(); users.add(new User(1, "张三", 20)); users.add(new User(2, "李四", 21)); users.add(new User(3, "王五", 22)); userMapper.insertUsers(users); // 批量更新用户 users = new ArrayList<>(); users.add(new User(1, "张三三", 23)); users.add(new User(2, "李四四", 24)); users.add(new User(3, "王五五", 25)); userMapper.updateUsers(users); // 批量删除用户 List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(2); ids.add(3); userMapper.deleteUsers(ids); // 批量查询用户 ids = new ArrayList<>(); ids.add(1); ids.add(2); List<User> userList = userMapper.selectUsers(ids); } finally { sqlSession.close(); } ``` 以上就是使用 MyBatis 的 `batch` 操作实现批量增删改查的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值