Xử lý đọc file dữ liệu lớn và đưa vào MySQL bằng Batch trong JDBC của Java

Trong bài viết này tôi sẽ hướng dẫn các bạn xử lý với bài toán số lớn cần đọc file dữ liệu có 1 triệu dòng thông tin sau đó sẽ sử dụng batch để đưa vào MySQL một cách nhanh nhất trong lập trình java.

JDBC Batch là gì trong lập trình Java ?

Trong JDBC của lập trình java, mỗi lần bạn thực hiện insert, update, delete hoặc select, ứng dụng sẽ kết nối tới cơ sở dữ liệu một lần.

Giả sử, bạn cần insert 1 triệu bản ghi vào database. Theo cách thông thường, chúng ta thực hiện insert 1 triệu lần thì sẽ phải kết nối tới database 1 triệu lần để thao tác với database sẽ tốn rất nhiều thời gian

Khi đó Ý tưởng dùng Batch (xử lý theo mẻ), tức là chúng ta sẽ kết nối 1 lần nhưng insert 100.000 bản ghi cùng lúc như vậy sẽ tiết kiệm được thời gian của 999.990 kết nối tới database.

Batch size:

Khi dùng batch xảy ra 1 vấn đề đó là nếu bạn insert 1 lần 100.000 bản ghi thì sẽ tốn rất nhiều bộ nhớ, nếu số lượng bản ghi nhiều hơn có thể hệ thống sẽ bị quá tải. Các bạn có thể chia nhỏ ra, ví dụ mỗi lần kết nối tới database sẽ insert 10.000 bản ghi (con số 10.000 gọi là batch size) như thế vừa đảm bảo tốc độ, vừa đảm bảo bộ nhớ. 


Hướng dẫn xử lý demo dữ liệu từ 1 triệu dòng đẩy vào MySQL bằng Batch

Sau đây tôi sẽ hướng dẫn viết code để giúp các bạn học lập trình java xử lý đẩy dữ liệu lớn đọc được từ file vào MySQL. Đầu tiên bạn có thể sử dụng lập trình để tạo một file chứa dữ liệu 1 triệu thông tin như ví dụ này là file tuyển sinh như hình dưới hoặc tải trực tiếp file: tại đây. Trong từng dòng thông tin được ngăn cách với nhau bằng dấu ; như hình dưới:

Thiết kế cơ sở dữ liệu trong với bảng dữ liệu TuyenSinh với cấu trúc như sau:

Sau đây là code xử lý để đọc file và đưa vào MySQL:

/**
     * Xử lý đọc dữ liệu từ file text chứa 1 triệu dòng sau đó inport vào MySQL
     * @param duongDan
     */
    public void docDuLieuTuFileImportToMySQL(String duongDan)
    {
        Connection conn = null;
        PreparedStatement comm = null;
        try{
        conn = DataProvider.ketNoi();
         
        conn.setAutoCommit(false);
         
        String strInsert = "Insert into TuyenSinh(HoTen, NgaySinh, Toan, Ly, Hoa, DiaChi) values(?, ?, ?, ?, ?, ?)";
                 
        comm = conn.prepareStatement(strInsert);
                         
        File file = new File(duongDan);
 
        try (Stream<String> lines = Files.lines(file.toPath(), StandardCharsets.UTF_8)) {
            int i = 0;
            for (String line : (Iterable<String>) lines::iterator) {
                    //System.out.println(line + "\r\n");
                     
                     String[] arr = line.split(";");
                      
                     comm.setString(1, arr[1]);
                     comm.setString(2, arr[2]);
                     comm.setString(3, arr[3]);
                     comm.setString(4, arr[4]);
                     comm.setString(5, arr[5]);
                     comm.setString(6, arr[6]);
                     comm.addBatch();
                      
                     if(i==10000)
                     {
                         i = 0;
                          
                         comm.executeBatch();//Thực hiện 1 mẻ
                         comm.clearBatch();//Xoá mẻ để chạy cho kế tiếp
                         System.out.println("Thêm dữ liệu vào db thành công");
                     }
                     i++;
            }
             
            comm.close();
            conn.commit();
 
        } catch (FileNotFoundException ex) {
            System.err.println("Không tìm thấy file. Chi tiết: " + ex.getMessage());
        } catch (IOException ex) {
            System.out.println("Có lỗi trong quá trình đọc file. Chi tiết: " + ex.getMessage());
        }
        } catch (SQLException ex) {
            try {
                comm.close();
                conn.rollback();
                System.out.println("Có lỗi khi insert data vào MySQL. Chi tiết: " + ex.getMessage());
            } catch (SQLException ex1) {
                Logger.getLogger(FlieBigToInsertMySQL.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
        
    }
Trong bài viết này tôi chạy thử với đọc 1 triệu dòng thông tin rồi đưa vào cơ sở dữ liệu MySQL trên Netbean báo kết quả mất 2 phút 04 giây. Đây là một kết quả tốt với lượng xử lý dữ liệu lớn. Hy vọng qua bài viết này các bạn đã hiểu rõ hơn về cách sử dụng batch của jdbc trong lập trình java. Nếu bạn muốn học lập trình java cùng chuyên gia giàu kinh nghiệm có thể tham khảo ngay tại đây: học java cùng chuyên gia.

=============================
☎ STANFORD – ĐÀO TẠO VÀ PHÁT TRIỂN CÔNG NGHỆ
Hotline: 0963 723 236 - 0866 586 366
Website: https://stanford.com.vn
Facebook: http://bit.ly/2FN0TYb
Youtube: http://bit.ly/2TkKT7I

Tags: học java cơ bản, học jdbc, khoá java cơ bản, batch trong jdbc, xử lý dữ liệu lớn với mysql, học java cùng chuyên gia