最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

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

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

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

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

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

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

第二種方案,是生成一條 SQL進行插入:

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

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

我們接下來會采用第二種方案進行實現(xiàn)。

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

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

采用多線程進行異步插入,提升性能;

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

接下來我們就來說說具體該怎么利用代碼進行實現(xiàn)。

三. 代碼實現(xiàn)

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

1.導入依賴

    <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)建啟動類

@SpringBootApplication  //引導類核心注解
@EnableScheduling //開啟定時任務
public class BatchApplication {
    public static void main(String[] args) {
        SpringApplication.run(BatchApplication.class,args);
    }
}

3.配置文件application.yml

server:
  port: 9999  # 指定端口號
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)建表與實體類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效率會比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.開啟定時任務

SpringBoot默認整合了scheduled,使用步驟如下:

在引導類加入@EnableScheduling注解,開啟定時任務;

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

業(yè)務層方法中開啟的線程可以根據(jù)當前機器的配置來修改。我們這里開了7個線程,每個線程去執(zhí)行20次循環(huán),一次添加5000條數(shù)據(jù)。這里要注意mybatis批量插入時,不建議超過10000條錯誤。因為數(shù)據(jù)量過大,容易出現(xià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("定時器被觸發(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.生成對象的util

我們用來模擬生成要插入的數(shù)據(jù),實際業(yè)務開發(fā)的時候可以是從excel中導入的數(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ù),線程池中能運行的最大線程數(shù);

keepAliveTime 保證存活時間,當線程空閑時間,多久會回收線程;

unit 和keepAliveTime配合使用,時間單位;

workQueue 工作隊列,用于存儲任務在任務被執(zhí)行之前。

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

9.完整項目結構

10.測試

總結 

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

相關文章

  • Java EE過濾器優(yōu)先級控制的實例解讀

    Java EE過濾器優(yōu)先級控制的實例解讀

    通過使用@Priority注解,可以控制JavaEE應用中過濾器的執(zhí)行順序,在上面的示例中,我們通過設置不同的優(yōu)先級,實現(xiàn)了TimeFilter和LogFilter的執(zhí)行順序控制
    2025-02-02
  • Java設計模式之狀態(tài)模式(State模式)介紹

    Java設計模式之狀態(tài)模式(State模式)介紹

    這篇文章主要介紹了Java設計模式之狀態(tài)模式(State模式)介紹,本文講解了何時使用狀態(tài)模式、如何使用狀態(tài)模式等內容,需要的朋友可以參考下
    2015-03-03
  • 深入淺析SPI機制在JDK與Spring?Boot中的應用

    深入淺析SPI機制在JDK與Spring?Boot中的應用

    SPI是一種使軟件框架或庫更加模塊化、可擴展和可維護的有效方法。通過遵循“開閉原則”,?SPI?確保了系統(tǒng)的穩(wěn)定性和靈活性,從而滿足了不斷變化的業(yè)務需求,這篇文章主要介紹了SPI機制在JDK與Spring?Boot中的應用,需要的朋友可以參考下
    2023-09-09
  • SpringBoot項目動態(tài)指定配置文件的方法示例

    SpringBoot項目動態(tài)指定配置文件的方法示例

    SpringBoot 作為 Java 開發(fā)中一個非常流行的框架,以其簡化配置和快速啟動應用而聞名,在開發(fā)過程中,我們經(jīng)常需要根據(jù)不同的環(huán)境來加載不同的配置文件,本文給大家介紹了SpringBoot項目動態(tài)指定配置文件的方法示例,需要的朋友可以參考下
    2024-12-12
  • 使用Redis incr解決并發(fā)問題的操作

    使用Redis incr解決并發(fā)問題的操作

    這篇文章主要介紹了使用Redis incr解決并發(fā)問題的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • SpringMVC 參數(shù)綁定意義及實現(xiàn)過程解析

    SpringMVC 參數(shù)綁定意義及實現(xiàn)過程解析

    這篇文章主要介紹了SpringMVC 參數(shù)綁定意義及實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • 詳解JAVA里面獲取map的key和value的方法

    詳解JAVA里面獲取map的key和value的方法

    這篇文章主要介紹了詳解JAVA里面獲取map的key和value的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-09-09
  • 十道java華為編程大賽題目

    十道java華為編程大賽題目

    這篇文章主要為大家分享了十道java華為編程大賽題目,代碼經(jīng)過調試,經(jīng)典的java編程題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • 解析Java多線程之常見鎖策略與CAS中的ABA問題

    解析Java多線程之常見鎖策略與CAS中的ABA問題

    本篇文章介紹了常見的鎖策略,并說明了synchronized關鍵字加的鎖類型不是單一一種鎖類型的,根據(jù)可重入鎖與非可重入鎖引出了死鎖的概念與死鎖條件,最后介紹了CAS指令以及CAS鎖產生的ABA問題及其解決方案,需要的朋友可以參考下
    2022-06-06
  • 解決Spring事務@Transactional多層嵌套失效問題

    解決Spring事務@Transactional多層嵌套失效問題

    在使用Spring進行事務管理時,可能會遇到事務失效的問題,主要原因包括數(shù)據(jù)庫不支持事務、方法訪問級別不是public、未被Spring管理的Bean、當前類的方法內部調用以及配置的事務傳播性不當?shù)?解決事務失效的方法有使用聲明式事務處理采用合適的事務傳播行為
    2024-11-11

最新評論

延边| 永定县| 莱芜市| 晴隆县| 庐江县| 滨海县| 论坛| 三都| 沧州市| 巢湖市| 云霄县| 福贡县| 修武县| 荃湾区| 天台县| 雅安市| 仪陇县| 根河市| 仙居县| 忻州市| 定结县| 安溪县| 波密县| 韩城市| 绥棱县| 玛曲县| 大方县| 桐庐县| 大石桥市| 临江市| 鄂州市| 卢湾区| 阿拉善右旗| 和龙市| 仲巴县| 七台河市| 拉萨市| 永和县| 呼伦贝尔市| 赣榆县| 安乡县|