mybatis进行百万批量插入(我行),mysql进行百万批量插入(我不行)

其他链接:

java mybatis分批次批量插入
https://blog.csdn.net/qq_33745371/article/details/106840104

mysql模糊查询 like与locate效率
https://blog.csdn.net/qq_33745371/article/details/106673790

mysql新建数据库字符集和排序规则
https://blog.csdn.net/qq_33745371/article/details/106459524

我会在最后附上链接供大家下载

我将sql文件放在了项目文件夹里面了,你们直接解压,然后创建数据库运行这个sql(三个字段,动手也行)
在这里插入图片描述

先上图,我用mysql存储过程的问题。

我用存储过程插入1W条测试数据,需要9秒,然后设置了100万条数据,我都睡醒了,才插入47W数据 ,平均一秒才七八个数据插入。用的不是insert into xxx values(),(),()…,就是单个的插入语句insert into xxx values(),作while循环(这种方式简单)。在这里插入图片描述
我在公司里没用过存储过程,只是自学过plsql,mysql的存储过程又和plsql有些不一样的地方,手生的很,mysql对存储过程支持也不是太好,所以不推荐了。

mybatis是咱们的强项啊!,咱们的目的是解决问题~

所以我这里使用的方法是,新建一个springboot项目,用mybatis批量插入百万数据,使用的是values(),(),()…500个为一条,这样我们只要2000条sql就有百万的记录。
先上最终执行时间:26秒
在这里插入图片描述
数据库数据很简单,只有三个字段,id是主键。
在这里插入图片描述
1.pom.xml和application.properties
1.1)pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.qwl</groupId>
    <artifactId>batchdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>batchdemo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.6</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

1.2)application.properties(有些没啥用的配置,不用管,这都不是重点)

#初始化连接数
spring.datasource.druid.initial-size=10
#最小空闲连接
spring.datasource.druid.min-idle=1
#最大活动连接
spring.datasource.druid.max-active=10
#获取连接时测试是否可用
spring.datasource.druid.test-on-borrow=true
#监控页面启动
spring.datasource.druid.stat-view-servlet.allow=true
server.port=8080
#数据库连接配置 #配置数据源类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/batchdemo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.initialSize=3       # 初始化,最小,最大连接数
spring.datasource.minidle=3
spring.datasource.maxActive=18
spring.datasource.maxWait=30000     # 获取数据库连接等待的超时时间
spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置多久进行一次检测,检测需要关闭的空闲连接 单位毫秒
#mapper配置文件
mybatis.mapper-locations=classpath:mapper/*.xml
#json时间转换
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
yzm.config.validateCode=loginCode

2.model包(实体类放这),Person类

package com.qwl.batchdemo.model;

/**
 * @author 齐威龙
 * @date 2020/6/8 15:06
 */
public class Person {
    /**
     * id
     */
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private Integer age;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

3.util包(工具类放这),随机生成姓名的RandomName 类

package com.qwl.batchdemo.util;

import java.util.Random;

/**
 * @author 齐威龙
 * @date 2020/6/8 17:01
 */
public class RandomName {
    /**
     * 姓氏
     */
    private static String firstName = "齐 赵 钱 孙 李 周 吴 郑 王 冯 陈 褚 卫 蒋 沈 韩 杨 朱 秦 尤 许 何 吕 施 张 孔 曹 严 华 金 魏 陶 姜 戚 谢 邹 喻 " +
            "柏 水 窦 章 云 苏 潘 葛 奚 范 彭 郎 万俟 司马 上官 欧阳 夏侯 诸葛 闻人 东方 赫连 皇甫 尉迟 公羊";
    /**
     * 名字
     */
    private static String secondName = "一、二、三、四、威龙、碧凡、夏菡、曼香、若烟、半梦、雅绿、冰蓝、灵槐、平安、书翠、翠风、香巧、代云、友巧、听寒、梦柏、醉易、访旋、亦玉、凌萱、访卉、怀亦、笑蓝、春翠、靖柏、书雪、乐枫、念薇、靖雁、寻春、恨山、从寒、忆香、觅波、静曼、凡旋、新波、代真、新蕾、雁玉、冷卉、紫山、千琴、恨天、傲芙、盼山、怀蝶、冰兰、问旋、从南、白易、问筠、如霜、半芹、寒雁、怜云、寻文、谷雪、乐萱、涵菡、海莲、傲蕾、青槐、冬儿、易梦、惜雪、宛海、之柔、夏青";

    private static Random random = new Random();

    public static String build(){
        //随机生成2或3
        int length = random.nextInt(2)+2;

        //随机生成姓
        Random r = new Random();
        String[] firstNameArr = firstName.split(" ");
        int index = r.nextInt(firstNameArr.length);
        //姓
        String name = firstNameArr[index];

        //名
        while (name.length()<length){
            int secondIndex = r.nextInt(secondName.length());
            String second = secondName.substring(secondIndex, secondIndex + 1);
            if(!"、".equals(second)){
                 name += second;
            }else{
                continue;
            }
        }
        return name;
    }

}

4.dao包,personDAO接口放这

package com.qwl.batchdemo.dao;

import com.qwl.batchdemo.model.Person;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @author 齐威龙
 * @date 2020/6/8 15:07
 */
@Mapper
public interface PersonDAO {
    /**
     * 批量插入
     * @return
     */
    int batchAddPerson(List<Person> personList);
}

5.mapper包,sqlmap_person.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.qwl.batchdemo.dao.PersonDAO">

    <insert id="batchAddPerson">
        insert into person(name,age) values
        <foreach collection="list" item="person" separator=",">
            (#{person.name},#{person.age})
        </foreach>
    </insert>
</mapper>

6.因为我只是为了插入百万数据,所以偷懒直接用controller调用dao层方法,在controller包下写逻辑,PersonController类。

package com.qwl.batchdemo.controller;

import com.qwl.batchdemo.dao.PersonDAO;
import com.qwl.batchdemo.model.Person;
import com.qwl.batchdemo.util.RandomName;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;

/**
 * @author 齐威龙
 * @date 2020/6/8 15:21
 */
@RestController
public class PersonController {
    @Resource
    PersonDAO personDAO;

    @PostMapping("/addPerson")
    public void addPerson(){
        long startTime = System.currentTimeMillis();
        for(int i=0;i<2000;i++){
            ArrayList<Person> personList  = new ArrayList<>();
            for(int j=0;j<500;j++){
                Person person = new Person();
                int age = (int)(Math.random()*120);
                person.setAge(age);
                person.setName(RandomName.build());
                personList.add(person);
            }
            personDAO.batchAddPerson(personList);
        }
        long endTime = System.currentTimeMillis();
        long time = endTime-startTime;
        System.out.println("耗时:"+time+"毫秒");
    }

}

百度云网盘链接
提取码:17uo

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiweilong123456

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值