亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

springboot+mybatis快速插入大量數(shù)據(jù)的具體實(shí)現(xiàn)

 更新時(shí)間:2023年04月17日 10:50:18   作者:馬劍威老師  
最近導(dǎo)入表格數(shù)據(jù)時(shí)需要同時(shí)插入修改大量數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于springboot+mybatis快速插入大量數(shù)據(jù)的具體實(shí)現(xiàn),文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在公司業(yè)務(wù)開(kāi)發(fā)過(guò)程中,我們經(jīng)常會(huì)遇到往數(shù)據(jù)庫(kù)表中插入大量數(shù)據(jù)的場(chǎng)景,比如excel批量導(dǎo)入數(shù)據(jù)。那么該如何快速地插入數(shù)據(jù)呢?我們可以考慮使用批量插入來(lái)實(shí)現(xiàn),該方案實(shí)測(cè)每秒能達(dá)到35000條,后附具體實(shí)現(xiàn)代碼。接下來(lái)我就給大家說(shuō)一下實(shí)現(xiàn)方式。

一. JDBC實(shí)現(xiàn)方案

用一個(gè) for 循環(huán),把數(shù)據(jù)一條一條地插入;生成一條插入 sql,類(lèi)似這種 insert into user(name,pwd) values('aa','123'),('cc','123')...

第一種方案,是用 for語(yǔ)句循環(huán)插入:

該方案的優(yōu)勢(shì)在于,JDBC 中的 PreparedStatement 有預(yù)編譯功能,預(yù)編譯之后會(huì)緩存起來(lái)。之后SQL執(zhí)行會(huì)比較快,且 JDBC可以開(kāi)啟批處理,這個(gè)批處理執(zhí)行非常給力。

劣勢(shì)在于,很多時(shí)候我們的 SQL 服務(wù)器和應(yīng)用服務(wù)器可能并不是同一臺(tái),所以必須要考慮網(wǎng)絡(luò) IO。如果網(wǎng)絡(luò) IO 比較費(fèi)時(shí)間的話,那么可能會(huì)拖慢 SQL 執(zhí)行的速度。

第二種方案,是生成一條 SQL進(jìn)行插入:

該方案的優(yōu)勢(shì)在于,只有一次網(wǎng)絡(luò) IO。即使分片處理也只是數(shù)次網(wǎng)絡(luò) IO,所以這種方案不會(huì)在網(wǎng)絡(luò) IO 上花費(fèi)太多時(shí)間。

當(dāng)然這種方案也有劣勢(shì)。一是 SQL 太長(zhǎng)了,甚至可能需要分片后批量處理;二是無(wú)法充分發(fā)揮 PreparedStatement 預(yù)編譯的優(yōu)勢(shì),SQL 要重新解析且無(wú)法復(fù)用;三是最終生成的 SQL 太長(zhǎng)了,數(shù)據(jù)庫(kù)管理器解析這么長(zhǎng)的 SQL 也需要時(shí)間。

我們接下來(lái)會(huì)采用第二種方案進(jìn)行實(shí)現(xiàn)。

二. 具體實(shí)現(xiàn)思路

如果我們想要拉高插入效率,肯定不能夠一條一條地插入了,必須得使用foreach批量插入;

采用多線程進(jìn)行異步插入,提升性能;

我們不可能單次提交多個(gè)insert,大量的插入操作會(huì)很耗時(shí),短時(shí)間內(nèi)完不成,可以采用定時(shí)任務(wù)來(lái)實(shí)現(xiàn)。

接下來(lái)我們就來(lái)說(shuō)說(shuō)具體該怎么利用代碼進(jìn)行實(shí)現(xiàn)。

三. 代碼實(shí)現(xiàn)

本案例主要是基于SpringBoot整合mybatis進(jìn)行實(shí)現(xiàn)。

1.導(dǎo)入依賴(lài)

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>

2.創(chuàng)建啟動(dòng)類(lèi)

@SpringBootApplication  //引導(dǎo)類(lèi)核心注解
@EnableScheduling //開(kāi)啟定時(shí)任務(wù)
public class BatchApplication {
    public static void main(String[] args) {
        SpringApplication.run(BatchApplication.class,args);
    }
}

3.配置文件application.yml

server:
  port: 9999  # 指定端口號(hào)
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: 123
mybatis:
  mapper-locations: classpath:mybatis/*.xml   #指定mapper映射文件路徑
  type-aliases-package: com.qfedu.model  # 別名

4.創(chuàng)建表與實(shí)體類(lèi)User

創(chuàng)建表:

CREATE TABLE `user` (
  `id` INT(11) NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(30) DEFAULT NULL,
  `pwd` VARCHAR(20) DEFAULT NULL,
  `sex` INT(11) DEFAULT NULL,
  `birthday` DATETIME DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8

注意:MyISAM效率會(huì)比INNODB快。

User.java

@Data
public class User {
    private int id;
    private String username;
    private String pwd;
    private int sex;
    private LocalDate birthday;
}

5.持久層mapper和映射文件

UserMapper.java

@Mapper
public interface UserMapper {
    void insertBatch(@Param("userList") List<User> userList);
}

UserMapper.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.qfedu.mapper.UserMapper">
    <insert id="addList" parameterType="User"  >
        insert  into user (username,pwd,sex,birthday) values
        <foreach collection="list" item="item" separator=",">
            (#{item.username}, #{item.pwd}, #{item.sex}, #{item.birthday})
        </foreach>
    </insert>
</mapper>

6.開(kāi)啟定時(shí)任務(wù)

SpringBoot默認(rèn)整合了scheduled,使用步驟如下:

在引導(dǎo)類(lèi)加入@EnableScheduling注解,開(kāi)啟定時(shí)任務(wù);

在業(yè)務(wù)層方法上加入 @Scheduled注解,定義cron表達(dá)式周期執(zhí)行。

業(yè)務(wù)層方法中開(kāi)啟的線程可以根據(jù)當(dāng)前機(jī)器的配置來(lái)修改。我們這里開(kāi)了7個(gè)線程,每個(gè)線程去執(zhí)行20次循環(huán),一次添加5000條數(shù)據(jù)。這里要注意mybatis批量插入時(shí),不建議超過(guò)10000條錯(cuò)誤。因?yàn)閿?shù)據(jù)量過(guò)大,容易出現(xiàn)棧內(nèi)存溢出的問(wèn)題。

@Component
public class UserServiceImpl {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    //線程池
    private ThreadPoolExecutor executor;
    @Scheduled(cron = "0/20 * * * * ?") //每隔20秒執(zhí)行一次
    public void  addList(){
        System.out.println("定時(shí)器被觸發(fā)");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 7; i++) {
 
            Thread thread = new Thread(() -> {
                try {
                    for (int j = 0; j < 20; j++) {
                        userMapper.addList(UserUtil.getUsers(5000));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
            try {
                executor.execute(thread);
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    }
}

7.生成對(duì)象的util

我們用來(lái)模擬生成要插入的數(shù)據(jù),實(shí)際業(yè)務(wù)開(kāi)發(fā)的時(shí)候可以是從excel中導(dǎo)入的數(shù)據(jù)。

public class UserUtil {
    private static Random random = new Random();
    public static List<User> getUsers(int num){
        List<User> users = new ArrayList<>();
        for (int i = 0;i<num;i++){
            User user = new User();
            user.setBirthday(LocalDate.now());
            user.setSex(random.nextInt(2));
            user.setPwd("123"+random.nextInt(100000));
            user.setUsername("batch"+random.nextInt(num));
            users.add(user);
        }
        return users;
    }
}

8.線程池配置

線程池參數(shù):

corePoolSize 核心線程數(shù),在線程池中要保證的最小線程數(shù);

mainumPoolSize 最大線程數(shù),線程池中能運(yùn)行的最大線程數(shù);

keepAliveTime 保證存活時(shí)間,當(dāng)線程空閑時(shí)間,多久會(huì)回收線程;

unit 和keepAliveTime配合使用,時(shí)間單位;

workQueue 工作隊(duì)列,用于存儲(chǔ)任務(wù)在任務(wù)被執(zhí)行之前。

@Configuration
public class ThreadPoolExecutorConfig {
    @Bean
    public ThreadPoolExecutor threadPoolExecutor() {
        //線程池中6個(gè)線程,最大8個(gè)線程,用于緩存任務(wù)的阻塞隊(duì)列數(shù)5個(gè)
        ThreadPoolExecutor executor = new ThreadPoolExecutor(6, 8, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100));
        executor.allowCoreThreadTimeOut(true);//允許超時(shí)
        return executor;
    }
}

9.完整項(xiàng)目結(jié)構(gòu)

10.測(cè)試

總結(jié) 

到此這篇關(guān)于springboot+mybatis快速插入大量數(shù)據(jù)的文章就介紹到這了,更多相關(guān)springboot mybatis快速插入大量數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea使用easyCode生成代碼(根據(jù)mybatis-plus模板創(chuàng)建自己的模板)

    idea使用easyCode生成代碼(根據(jù)mybatis-plus模板創(chuàng)建自己的模板)

    本文主要介紹了idea使用easyCode生成代碼,easyCode代碼生成器可以減少低價(jià)值搬磚,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 利用Java實(shí)現(xiàn)網(wǎng)站聚合工具

    利用Java實(shí)現(xiàn)網(wǎng)站聚合工具

    互聯(lián)網(wǎng)上有數(shù)以萬(wàn)億計(jì)的網(wǎng)站,每個(gè)網(wǎng)站大都具有一定的功能。搜索引擎雖然對(duì)互聯(lián)網(wǎng)上的部分網(wǎng)站建立了索引,但是其作為一個(gè)大而全的搜索系統(tǒng),無(wú)法很好的定位到一些特殊的需求。因此本文將介紹一個(gè)用java實(shí)現(xiàn)的網(wǎng)站數(shù)據(jù)聚合工具,需要的可以參考一下
    2022-01-01
  • Springboot @Configuration與自動(dòng)配置詳解

    Springboot @Configuration與自動(dòng)配置詳解

    這篇文章主要介紹了SpringBoot中的@Configuration自動(dòng)配置,在進(jìn)行項(xiàng)目編寫(xiě)前,我們還需要知道一個(gè)東西,就是SpringBoot對(duì)我們的SpringMVC還做了哪些配置,包括如何擴(kuò)展,如何定制,只有把這些都搞清楚了,我們?cè)谥笫褂貌艜?huì)更加得心應(yīng)手
    2022-07-07
  • springboot整合spring-data-redis遇到的坑

    springboot整合spring-data-redis遇到的坑

    使用springboot整合redis,使用默認(rèn)的序列化配置,然后使用redis-client去查詢時(shí)查詢不到相應(yīng)的key.問(wèn)題出在哪,怎么解決呢?下面小編給大家?guī)?lái)了springboot整合spring-data-redis遇到的坑,需要的的朋友參考下吧
    2017-04-04
  • java獲取鼠標(biāo)在屏幕上坐標(biāo)的方法

    java獲取鼠標(biāo)在屏幕上坐標(biāo)的方法

    本文介紹的是如何用java獲取鼠標(biāo)在屏幕上的坐標(biāo),這個(gè)功能其實(shí)沒(méi)什么難度可言,在這里分享給大家,是因?yàn)橛袝r(shí)候我們需要這個(gè)工具,Java作為跨平臺(tái)語(yǔ)言的優(yōu)勢(shì)在這個(gè)軟件就可以體現(xiàn)出來(lái),不需修改就可以在windows、mac、Linux上使用這個(gè)軟件。下面來(lái)一起看看詳細(xì)的介紹吧。
    2016-12-12
  • springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)

    springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)

    在開(kāi)發(fā)中,動(dòng)態(tài)數(shù)據(jù)源配置還是用的比較多的,比如在多數(shù)據(jù)源使用方面,又或者是在多個(gè)DB之間切換方面。這里給出一個(gè)動(dòng)態(tài)數(shù)據(jù)源的配置方案,感興趣的可以了解一下
    2021-07-07
  • Spring遠(yuǎn)程調(diào)用HttpClient/RestTemplate的方法

    Spring遠(yuǎn)程調(diào)用HttpClient/RestTemplate的方法

    這篇文章主要介紹了Spring遠(yuǎn)程調(diào)用HttpClient/RestTemplate的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 手寫(xiě)mybatis完整sql插件問(wèn)題及實(shí)現(xiàn)思路

    手寫(xiě)mybatis完整sql插件問(wèn)題及實(shí)現(xiàn)思路

    大家在使用mybatis的過(guò)程中,mysql日志功能一般不會(huì)直接放到數(shù)據(jù)庫(kù)中執(zhí)行的,今天小編重點(diǎn)給大家分享手寫(xiě)mybatis完整sql插件問(wèn)題及實(shí)現(xiàn)思路,對(duì)mybatis完整sql插件相關(guān)知識(shí)感興趣的朋友一起看看吧
    2021-05-05
  • Swing常用組件之單選按鈕和復(fù)選框

    Swing常用組件之單選按鈕和復(fù)選框

    Swing是一個(gè)用于開(kāi)發(fā)Java應(yīng)用程序用戶界面的開(kāi)發(fā)工具包,這篇文章主要介紹了Swing常用組件之單選按鈕和復(fù)選框,感興趣的朋友可以參考一下
    2016-05-05
  • Springboot整合PageOffice 實(shí)現(xiàn)word在線編輯保存功能

    Springboot整合PageOffice 實(shí)現(xiàn)word在線編輯保存功能

    這篇文章主要介紹了Springboot整合PageOffice 實(shí)現(xiàn)word在線編輯保存,本文以Samples5 為示例文件結(jié)合示例代碼給大家詳細(xì)介紹,需要的朋友可以參考下
    2021-08-08

最新評(píng)論