Werfen wir zunächst einen Blick auf unser Ziel: Batch-Einfügung von 10.000 Daten in die MySQL-Datenbank
Betriebsumgebung: MySQL- und Java-Code laufen beide auf meinem lokalen Windows-Computer (i7-Prozessor, 4 Kerne, 16G läuft). Speicher, 64-Bit-Betriebssystem
1. JPA-Single-Threaded-Ausführung
Code weggelassen, dauert es etwa 39S
2. JPA-Multithread-Ausführung
dauert etwa 37S, was nicht viel ist schneller als erwartet Im Gegensatz dazu bedeutet Multithreading im Rahmen von JPA mehrere Verbindungen, verbraucht jedoch mehr Datenbankleistung
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. Die herkömmliche JDBC-Einfügung dauert etwa 8 Sekunden, was viel schneller ist als die ersten beiden Methoden. Der Code lautet wie folgt: rrree4. Überprüfen Sie, ob die Daten insgesamt gespeichert wurden und keine Daten verloren gegangen sind.
Verwandte Empfehlungen:
Java-Einführungs-TutorialDas obige ist der detaillierte Inhalt vonJava Batch fügt große Datenmengen in die MySQL-Datenbank ein. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!