• SpringBoot快速插入Mysql 1000万条数据


    导读

      有时候为了验证系统瓶颈,需要往数据库表中插入大量数据,可以写sheel脚本插入,前几天为了插入100万条数据,走的sheel脚本(点我直达),插入速度简直无法直视,花了3小时,才插入了10万条,后来没辙了,多跑几次sheel脚本(算是多线程操作吧),最终花了4个多小时才插入100万条记录。今天使用java程序快速插入1000万条数据,最终只需要3分钟多一点就搞定了,好了下面开始吧~

    添加依赖

            <!--lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.16</version>
            </dependency>
            <!--mysql-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <!--mybatis plus和spring boot整合-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.4.0</version>
            </dependency>
            <!--Druid连接池-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
            <!-- guava -->
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>31.0.1-jre</version>
            </dependency>

    application.properties

    # 端口号
    server.port=9999
    #===========数据库相关=============
    #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    #spring.datasource.url=jdbc:mysql://127.0.0.1/shop?useUnicode=true&characterEncoding=utf-8&useSSL=false
    #spring.datasource.username=root
    #spring.datasource.password=root
    # mybatis plus下划线转驼峰
    mybatis-plus.configuration.map-underscore-to-camel-case=true
    # 配置mybatis plus打印sql日志
    #mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    spring.datasource.name=mysql_test
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    # druid配置
    # 监控统计拦截的filters
    spring.datasource.druid.filters=stat
    spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.druid.url=jdbc:mysql://127.0.0.1/yb_mysql?useUnicode=true&characterEncoding=utf-8&useSSL=false
    spring.datasource.druid.username=root
    spring.datasource.druid.password=root
    #配置初始化大小/最小/最大
    spring.datasource.druid.initial-size=1
    spring.datasource.druid.min-idle=1
    spring.datasource.druid.max-active=20
    #获取连接等待超时时间
    spring.datasource.druid.max-wait=60000
    #间隔多久进行一次检测,检测需要关闭的空闲连接
    spring.datasource.druid.min-evictable-idle-time-millis=300000
    spring.datasource.druid.validation-query= SELECT 'x'
    spring.datasource.druid.test-while-idle=true
    spring.datasource.druid.test-on-borrow=true
    spring.datasource.druid.test-on-return=false

    数据库表结构

    实体类

    package com.ybchen.domain;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    import java.io.Serializable;
    
    /**
     * <p>
     * 用户表
     * </p>
     *
     * @author chenyanbin
     * @since 2021-11-07
     */
    @Data
    @EqualsAndHashCode(callSuper = false)
    @TableName("user")
    public class UserDO implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 主键
         */
        @TableId(value = "id", type = IdType.AUTO)
        private Long id;
    
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 备注
         */
        private String remark;
    
    
    }

    Mapper

    package com.ybchen.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.ybchen.domain.UserDO;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    public interface UserMapper extends BaseMapper<UserDO> {
        /**
         * 批量插入
         * @param userList
         * @return
         */
        int batchInsert(@Param("listUser") List<UserDO> userList);
    }
    <?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.ybchen.mapper.UserMapper">
    
        <!-- 通用查询映射结果 -->
        <resultMap id="BaseResultMap" type="com.ybchen.domain.UserDO">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="remark" property="remark"/>
        </resultMap>
    
        <!-- 通用查询结果列 -->
        <sql id="Base_Column_List">
            id, name, remark
        </sql>
    
        <!-- 批量插入 -->
        <insert id="batchInsert">
            insert into user (`name`,`remark`)
            values
            <foreach collection="listUser" item="item" separator=",">
                (#{item.name},#{item.remark})
            </foreach>
        </insert>
    </mapper>

    Controller

    package com.ybchen.controller;
    
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.google.common.collect.Lists;
    import com.ybchen.domain.UserDO;
    import com.ybchen.mapper.UserMapper;
    import com.ybchen.utils.JsonData;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.CountDownLatch;
    
    /**
     * @Author:chenyanbin
     */
    @RestController
    public class UserController {
        @Autowired
        UserMapper userMapper;
    
        @GetMapping("batchInsert")
        public JsonData batchInsert() {
            int num = 2000;
            CountDownLatch latch = new CountDownLatch(1);
            List<UserDO> userList = new ArrayList<>();
            new Thread(() -> {
                for (int i = 0; i < 10000000; i++) {
                    UserDO userDO = new UserDO();
                    userDO.setName("陈彦斌====》" + i);
                    userDO.setRemark("博客地址:https://www.cnblogs.com/chenyanbin/");
                    userList.add(userDO);
                }
                latch.countDown();
            }).start();
            try {
                latch.await();
            } catch (InterruptedException e) {
            }
            //2000条为一批,插入1000万条
            List<List<UserDO>> partition = Lists.partition(userList, num);
            partition.stream().forEach(user -> {
                int rows = userMapper.batchInsert(user);
                System.err.println("插入数据成功,rows:" + rows);
            });
            return JsonData.buildSuccess();
        }
    
        @GetMapping("all")
        public JsonData all(){
            return JsonData.buildSuccess(userMapper.selectList(new LambdaQueryWrapper<>()));
        }
    }

    项目结构

    演示

    最终耗时

    存储过程方式

    delimiter ;;
    create procedure chenyanbin()
    begin
      declare i int;
      set i=1;
      while(i<=3000000)do
        insert into test_excel (name1,name2,name3,name4,name5,name6,name7,name8,name9,name10,name11,name12,name13,name14,name15)
         values(concat('列1-:',i), concat('列2-:',i), concat('列3-:',i), concat('列4-:',i), concat('列5-:',i), concat('列6-:',i), concat('列7-:',i), concat('列8-:',i), concat('列9-:',i), concat('列10-:',i), concat('列11-:',i), concat('列12-:',i), concat('列13-:',i), concat('列14-:',i), concat('列15-:',i));
        set i=i+1;
      end while;
    end;;
    delimiter ;
    call chenyanbin();
    作者:陈彦斌

    个性签名:没有学不会的技术,只有不学习的人!
    联系方式:543210188(WeChat/QQ),推荐WeChat
  • 相关阅读:
    Android APK反编译
    android 安卓APP获取手机设备信息和手机号码的代码示例
    Android-- ArrayAdapter用法举例(转载)
    Android--ListView 分割线
    Android——检测TXT文件中是否含有双字节字符
    Android--------从一个包中的Avtivity创建另外另外一个包的Context
    百度地图技术大揭秘
    Lotusscript统计在线用户数
    代理中如何获取参数么
    DXL之通过程序修改Domino的设计
  • 原文地址:https://www.cnblogs.com/chenyanbin/p/15522096.html
Copyright © 2020-2023  润新知