首頁> Java> Java入門> 主體

java向mysql資料庫批量插入大量數據

王林
發布: 2021-05-01 12:00:26
轉載
9363 人瀏覽過

java向mysql資料庫批量插入大量數據

首先看下我們的目標:向mysql資料庫中批次插入10000條資料

操作環境:Mysql和Java程式碼都運行在我本機Windows電腦(i7處理器,4核,16G運行內存,64位元作業系統

1、JPA單執行緒執行

程式碼省略,大概需要39S左右

java向mysql資料庫批量插入大量數據

2、JPA多執行緒執行

java向mysql資料庫批量插入大量數據

大概要37S左右,並沒有想像中的快很多

(免費學習影片分享:java影片教學

原因: 多執行緒只是大幅提高了程式處理資料的時間,並不會提高插入資料庫的時間,相反地在我這邊JPA的框架下,多執行緒也意味著多連接,反而更消耗資料庫效能

package com.example.demo.controller; import com.example.demo.entity.Student; import com.example.demo.service.StudentServiceInterface; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.xml.bind.ValidationException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @RestController @RequestMapping("/student") public class StudentController { @Autowired private StudentServiceInterface studentServiceInterface; // 来使主线程等待线程池中的线程执行完毕 private CountDownLatch threadsSignal; // 每个线程处理的数据量 private static final int count = 1000; // 我的电脑为4核 线程池大小设置为2N+1 private static ExecutorService execPool = Executors.newFixedThreadPool(9); /** * 多线程保存 * * @return * @throws ValidationException */ @GetMapping() public String saveStudentEnableThread() throws ValidationException { Long begin = new Date().getTime(); // 需要插入数据库的数据 List list = new ArrayList<>(); for (int i = 0; i < 10000; i++) { Student student = new Student(); student.setName("张三"); student.setAge(10); list.add(student); } try { if (list.size() <= count) { threadsSignal = new CountDownLatch(1); execPool.submit(new InsertDate(list)); } else { List> lists = dealData(list, count); threadsSignal = new CountDownLatch(lists.size()); for (List students : lists) { execPool.submit(new InsertDate(students)); } } threadsSignal.await(); } catch (Exception e) { System.out.println(e.toString() + " 错误所在行数:" + e.getStackTrace()[0].getLineNumber()); } // 结束时间 Long end = new Date().getTime(); return "10000条数据插入花费时间 : " + (end - begin) / 1000 + " s"; } /** * 数据组装 * 把每个线程要处理的数据 再组成一个List * 我这边就是把10000条数据 组成 10个1000条的集合 * * @param target 数据源 * @param size 每个线程处理的数量 * @return */ public static List> dealData(List target, int size) { List> threadList = new ArrayList>(); // 获取被拆分的数组个数 int arrSize = target.size() % size == 0 ? target.size() / size : target.size() / size + 1; for (int i = 0; i < arrSize; i++) { List students = new ArrayList(); //把指定索引数据放入到list中 for (int j = i * size; j <= size * (i + 1) - 1; j++) { if (j <= target.size() - 1) { students.add(target.get(j)); } } threadList.add(students); } return threadList; } /** * 内部类,开启线程批量保存数据 */ class InsertDate extends Thread { List list = new ArrayList(); public InsertDate(List students) { list = students; } public void run() { try { // 与数据库交互 studentServiceInterface.save(list); threadsSignal.countDown(); } catch (ValidationException e) { e.printStackTrace(); } } } }
登入後複製

3、傳統JDBC插入

java向mysql資料庫批量插入大量數據

大概要8S左右,相較於前兩種方式已經快很多了,程式碼如下:

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.xml.bind.ValidationException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.util.Date; @RestController @RequestMapping("/student1") public class StudentController1 { @GetMapping() public String saveStudentEnableThread() throws ValidationException { // 开始时间 Long begin = new Date().getTime(); Connection connection = null; try { connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db01?characterEncoding=utf8&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true", "admin", "123456");//获取连接 if (connection != null) { System.out.println("获取连接成功"); } else { System.out.println("获取连接失败"); } //这里必须设置为false,我们手动批量提交 connection.setAutoCommit(false); //这里需要注意,SQL语句的格式必须是预处理的这种,就是values(?,?,...,?),否则批处理不起作用 PreparedStatement statement = connection.prepareStatement("insert into student(id,`name`,age) values(?,?,?)"); // 塞数据 for (int i = 0; i < 10000; i++) { statement.setInt(1, i+1); statement.setString(2, "张三"); statement.setInt(3, 10); //将要执行的SQL语句先添加进去,不执行 statement.addBatch(); } // 提交要执行的批处理,防止 JDBC 执行事务处理 statement.executeBatch(); connection.commit(); // 关闭相关连接 statement.close(); connection.close(); } catch (Exception e) { e.printStackTrace(); } // 结束时间 Long end = new Date().getTime(); // 耗时 System.out.println("10000条数据插入花费时间 : " + (end - begin) / 1000 + " s"); return "10000条数据插入花费时间 : " + (end - begin) / 1000 + " s"; } }
登入後複製

4、最後檢查一下資料是否成功儲存庫,一共30000條,沒有丟資料

java向mysql資料庫批量插入大量數據

完成!

相關推薦:java入門教學

#

以上是java向mysql資料庫批量插入大量數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:csdn.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!