您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關使用java怎么向mysql數據庫批量插入數據,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
Java主要應用于:1. web開發;2. Android開發;3. 客戶端開發;4. 網頁開發;5. 企業級應用開發;6. Java大數據開發;7.游戲開發等。
1、JPA單線程執行
代碼省略,大概需要39S左右
2、JPA多線程執行
大概需要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<Student> 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<List<Student>> lists = dealData(list, count); threadsSignal = new CountDownLatch(lists.size()); for (List<Student> 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<List<Student>> dealData(List<Student> target, int size) { List<List<Student>> threadList = new ArrayList<List<Student>>(); // 獲取被拆分的數組個數 int arrSize = target.size() % size == 0 ? target.size() / size : target.size() / size + 1; for (int i = 0; i < arrSize; i++) { List<Student> students = new ArrayList<Student>(); //把指定索引數據放入到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<Student> list = new ArrayList<Student>(); public InsertDate(List<Student> students) { list = students; } public void run() { try { // 與數據庫交互 studentServiceInterface.save(list); threadsSignal.countDown(); } catch (ValidationException e) { e.printStackTrace(); } } } }
3、傳統JDBC插入
大概需要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數據庫批量插入數據有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。