IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Mybatis Batch模式和foreach标签批量插入数据效率对比 -> 正文阅读

[Java知识库]Mybatis Batch模式和foreach标签批量插入数据效率对比

Mybatis批处理效率

前言: 搭建mybatis测试环境

application.yml

注意: url后面必须加上 rewriteBatchedStatements=true 才能开启batch模式

# 数据源配置
spring:
  datasource:
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
    username: root
    password: 1511
    type: org.springframework.jdbc.datasource.DriverManagerDataSource
mybatis:
  type-aliases-package: com.dzw.domain
  mapper-locations: classpath*:mapper/*Mapper.xml
  #executor-type: batch #批处理
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

entity.Text

public class Text {

    private int id;
    private String name;
    private int sex;
    private String text;
}

mapper.TextMapper

public interface TextMapper {
    public void insert(Text text);

    void insertFor(List<Text> list);

    List<Text> findAll();
}

service

public interface TextService {
        public void insert(List<Text> list);
        List<Text> findAll();

        void insertFor(List<Text> list);

}

serviceImpl

@Service
public class TextServiceImpl implements TextService {

    @Autowired
    private TextMapper textMapper;

    @Override
    public void insert(List<Text> list) {

    }

    @Override
    public List<Text> findAll() {
        return textMapper.findAll();
    }

    @Override
    public void insertFor(List<Text> list) {
        textMapper.insertFor(list);
    }
}

DemoApplication

@SpringBootApplication
@MapperScan(basePackages = "com.dzw.mapper")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

TextMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dzw.mapper.TextMapper">
    <insert id="insert" parameterType="com.dzw.domain.Text" useGeneratedKeys="true">
        insert into text(name,sex,text) value(#{name},#{sex},#{text})
    </insert>

    <insert id="insertFor" parameterType="list" useGeneratedKeys="true">
        insert into text(name,sex,text) value
        <foreach collection="list" item="text"  separator=",">
            (#{text.name},#{text.sex},#{text.text})
        </foreach>

    </insert>

    <select id="findAll" resultType="com.dzw.domain.Text">
        select * from text
    </select>
</mapper>

text.sql

/*
 Navicat Premium Data Transfer

 Source Server         : localhost_3306
 Source Server Type    : MySQL
 Source Server Version : 50733
 Source Host           : localhost:3306
 Source Schema         : demo

 Target Server Type    : MySQL
 Target Server Version : 50733
 File Encoding         : 65001

 Date: 28/05/2022 15:24:50
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for text
-- ----------------------------
DROP TABLE IF EXISTS `text`;
CREATE TABLE `text`  (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `sex` tinyint(4) NULL DEFAULT NULL,
  `text` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 91008 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

测试数据: 10000条数据插入时间对比

1.batch模式

@Autowired
private SqlSessionFactory sqlSessionFactory;

@Test
void contextLoads() {
    //批量处理效率
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH); //批处理模式
    TextMapper mapper = sqlSession.getMapper(TextMapper.class);
    long start = System.currentTimeMillis();
    for (int i = 0; i < 10000; i++) {
        Text text = new Text();
        text.setName(String.valueOf(i));
        text.setSex(1);
        text.setText(String.valueOf(i));
        mapper.insert(text);
    }
    /**
     * Batch模式下 flushStatements方法 实际就是执行 BatchExecutor.doFlushStatements方法
     * 该方法会刷新statement
     */
    sqlSession.flushStatements();
    System.out.println(System.currentTimeMillis()-start); // 885  860  853

}

2.foreach模式

@Autowired
private TextService textService;

@Test
void insertFor() {
    //foreach标签批量处理效率
    long start = System.currentTimeMillis();
    ArrayList<Text> texts = new ArrayList<>();
    for (int i = 0; i < 10000; i++) {
        Text text = new Text();
        text.setName(String.valueOf(i));
        text.setSex(1);
        text.setText(String.valueOf(i));
        texts.add(text);

        if(texts.size()>=10000){
            textService.insertFor(texts);
            texts.clear();
        }
    }

    /**
     *  500 -> 1396 1396 1379
     *  2000 -> 1096 1052 1091
     *  10000 -> 1032 1006 973
     */
    System.out.println(System.currentTimeMillis()-start);


}

3.总结

###  mybatis batch模式和foreach标签 进行批量插入操作时 ,耗时对比

 batch 三次插入1w条数据耗时
        	885  860  853 平均:866

 foreach 三次插入1w条数据耗时
        	500 1313 1288              平均:1292
        	2000 -> 1096 1052 1091     平均:1079
        	10000 -> 1032 1006 973     平均:1003
 注意: 由于foreach时拼接sql数据,该方法会存在语句长度限制,有可能会抛出Could not execute JDBC batch update异常
      	  my.ini中修改以下配置
         		 max_allowed_packet=1M
          		net_buffer_length=2K
 对比:
    		1292/866 = 1.49
      	batch插入速度比foreach要快很多。

  结论: foreach标签对比batch模式 效率慢了0.5,java代码进行for循环批量插入就不测试了,肯定要慢几十倍

我在网上看了很多文章,都是foreach效率比batch高,可能时jdbc url没加上 rewriteBatchedStatements=true的原因,如有错误请各位斧正。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:02:20  更:2022-06-01 15:07:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:01:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码