Java将一个列表平均分成多个列表算法和MyBatis批量执行

最近帮别人写代码,经常遇到需要将一个 List 分成几等份然后分别操作。比如将一个列表,大小未知,很可能比较大,插入到数据库中,如果我们直接遍历执行 insert into,成本太高,主要消耗在网络延迟上。而如果直接将这1000条数据批量插入,可能会出现SQL太长无法执行成功的问题。

所以,最简单的方法就是将这个列表分成10份,每份100条数据,分10次插入,速度快大大提升。

下面分享一个分割列表的算法

  1. /**
  2.     * 将一个list均分成n个list,主要通过偏移量来实现的
  3.     *
  4.     * @param source
  5.     * @return
  6.     */
  7.    public <T> List<List<T>> averageAssign(List<T> source, int n) {
  8.        List<List<T>> result = new ArrayList<List<T>>();
  9.        //(先计算出余数)
  10.        int remaider = source.size() % n;
  11.        //然后是商
  12.        int number = source.size() / n;
  13.        //偏移量
  14.        int offset = 0;
  15.        for (int i = 0; i < n; i++) {
  16.            List<T> value = null;
  17.            if (remaider > 0) {
  18.                value = source.subList(i * number + offset, (i + 1) * number + offset + 1);
  19.                remaider--;
  20.                offset++;
  21.            } else {
  22.                value = source.subList(i * number + offset, (i + 1) * number + offset);
  23.            }
  24.            result.add(value);
  25.        }
  26.        return result;
  27.    }

 

使用例子

  1. //        for (Device device : deviceList) {
  2. //            deviceMapper.insert(device);
  3. //        }
  4.         //改成批量插入
  5.         //deviceList 是一个比较大的列表
  6.         List<List<Device>> lists = averageAssign(deviceList, deviceList.size() / 100 + 1);
  7.         for (List<Device> devices : lists) {
  8.             deviceMapper.batchInsert(devices);
  9.         }

 

关于批量执行多行SQL这里也说明一下

jdbc url 需要添加 &allowMultiQueries=true

 

mybatis xml

  1. <insert id="batchInsert">
  2.      <foreach collection="list" index="index" item="item">
  3.          INSERT INTO `device` (
  4.          xxx,yyy
  5.          )
  6.          VALUES (
  7.          #{item.xxx}, #{item.yyy}
  8.          );
  9.      </foreach>
  10.  </insert>

注意末尾需要加分号

 

  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
言曌

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: