MyBatis&MySQL常用操作

mybatis批量操作

操作数据库(mysql)属于io操作 io是很慢的 sql优化先不谈 那么首先要做的就是减少与数据库建立连接的次数 这时候批量操作就显得尤为重要 主要讲的是 forearch标签 

参数

  1. collection:要迭代的数组或集合的名称。
  2. item:当前迭代的元素的名称。
  3. index:当前迭代的元素在数组或集合中的索引。
  4. open:迭代开始时的 XML 标记。
  5. close:迭代结束时的 XML 标记。
  6. separator:迭代元素之间的分隔符。

查询

 这个就是一个非常之常用的啦,也就是mysql里面的in 操作

 <select id="batchQuery" resultType="java.util.LinkedHashMap">
        select
        id ,name,age
        where
       sex = 0 and  id in
         <foreach collection="list"  item="item" open="(" close=")" separator=",">
             #{item}
        </foreach>
    </select>

插入

批量插入前 需要注意 因为循环迭代 最终的sql可能会变得很长很长 过长时需要通过一些限制的方法

 private void batchInsert(List<Map<String, Object>> result) {、
//batchSize 为你限制每次最多可以插入的条数 我是写在配置文件里面了方便调试
        if (result.size() != 0) {
            System.out.println("数据总量 : " + result.size());

            // 计算需要分批插入的次数
            int totalBatches = (int) Math.ceil((double) result.size() / batchSize);

            // 循环插入每个批次的数据
            for (int i = 0; i < totalBatches; i++) {
                int fromIndex = i * batchSize;
                int toIndex = Math.min((i + 1) * batchSize, result.size());

                List<Map<String, Object>> batch = result.subList(fromIndex, toIndex);

                // 执行插入操作
                dataMapper.batchInsertMap(batch);

                System.out.println("插入第 " + (i + 1) + "次 数据量为:  " + batch.size() + " 还剩 " + (totalBatches - i - 1) + "次");
            }
        }

    }
 <insert id="batchInsert">
        INSERT INTO table(name,age,sex)
        VALUES
        <foreach collection="result" item="list" separator=",">
                (#{list.name},#{list.age},#{list.sex})
        </foreach>
    </insert>

上面针对于批量插入的解决方案 那么问题来了 如果说有些字段 被设置为唯一索引 那么插入的时候会报异常 由于是批量插入 就会导致插入失败(异常前插入的是否成功先不研究,要从源头解决问题),千万不要for循环单条插入并捕获异常...

以下是正确的解决方案(我原来也不会,但是学会了就是自己的!) 选择适合当前业务的

插入冲突做更新

这个操作也就是将原来冲突的进行删除 再添加 用到关键字 REPLACE  也就是替换

 <insert id="batchInsert">
        REPLACE INTO table(name,age,sex)
        VALUES
        <foreach collection="result" item="list" separator=",">
                (#{list.name},#{list.age},#{list.sex})
        </foreach>
    </insert>
插入冲突忽略/跳过

这个操作遇到冲突时就会直接跳过此次插入 

 <insert id="batchInsert">
   ---mysql数据库不加 or 目前数据库 sqllite
      INSERT or IGNOREINTO table(name,age,sex)
        VALUES
        <foreach collection="result" item="list" separator=",">
                (#{list.name},#{list.age},#{list.sex})
        </foreach>
    </insert>

删除

这个就没什么好赘述的了

  <delete id="batchDelete">
        delete
        from table
        WHERE id IN
        <foreach collection="idList" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </delete>

更新

这个操作之前连接数据库需要加一个参数 &allowMultiQueries=true 这个参数允许在单个连接上执行多个 SQL 查询 因为被分号分隔会视为多条sql 但是他还是有点慢。。建议做成异步的或者 case when 实现真正的批量 

并且注意分隔符 是分号

    <update id="batchUpdate" parameterType="java.util.List">
        <foreach collection="list" item="item" separator=";">
            update table
            <set>
                name=#{item.name},
                age= #{item.age}
            </set>
            where id = #{item.id}
        </foreach>
    </update>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值