其他链接:
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