Apache Derby Bài 34: Công cụ Import/Export dữ liệu hàng loạt (Bulk Import/Export)
1. Nhu cầu Import/Export dữ liệu hàng loạt
Trong quá trình vận hành hệ thống, bạn sẽ thường xuyên đối mặt với các kịch bản:
-
Chuyển đổi dữ liệu (Migration) từ một hệ quản trị CSDL khác (như MySQL, SQL Server) sang Apache Derby.
-
Kết xuất (Export) dữ liệu báo cáo doanh thu ra định dạng CSV để gửi cho bộ phận Kế toán xử lý trên Excel.
-
Nạp hàng triệu bản ghi danh mục sản phẩm từ file văn bản vào hệ thống.
Nếu bạn đọc từng dòng file CSV bằng Java và gọi lệnh INSERT 1 triệu lần, hệ thống sẽ mất rất nhiều thời gian và tài nguyên. Để giải quyết bài toán này, Apache Derby cung cấp sẵn các thủ tục hệ thống (System Procedures) thuộc schema SYSCS_UTIL giúp nhập/xuất file CSV trực tiếp ở tốc độ cực cao, bỏ qua các bước phân tích cú pháp SQL trung gian.
2. Xuất dữ liệu ra file (Export)
Derby cung cấp hai thủ tục để xuất dữ liệu ra file vật lý trên ổ cứng máy chủ: xuất toàn bộ bảng hoặc xuất theo một câu truy vấn tùy chỉnh.
2.1. Xuất toàn bộ bảng (SYSCS_EXPORT_TABLE)
Cú pháp:
SQL
CALL SYSCS_UTIL.SYSCS_EXPORT_TABLE (
'TEN_SCHEMA', 'TEN_BANG', 'DUONG_DAN_FILE',
'DAU_PHAN_CACH_COT', 'DAU_BAO_CHUOI', 'ENCODING'
);
Ví dụ: Xuất bảng san_pham ra file CSV, dùng dấu phẩy , để phân cách cột, dấu ngoặc kép " để bao bọc chuỗi, và mã hóa UTF-8 để không bị lỗi tiếng Việt:
SQL
CALL SYSCS_UTIL.SYSCS_EXPORT_TABLE (
'APP', 'SAN_PHAM', 'D:/bao_cao/san_pham_export.csv',
',', '"', 'UTF-8'
);
(Lưu ý: Tên Schema và Tên Bảng phải viết HOA nếu lúc tạo bảng bạn không dùng dấu nháy kép).
2.2. Xuất dữ liệu theo truy vấn (SYSCS_EXPORT_QUERY)
Nếu bạn chỉ muốn xuất dữ liệu của những sản phẩm đang giảm giá (không xuất toàn bảng), hãy dùng thủ tục Export Query:
SQL
CALL SYSCS_UTIL.SYSCS_EXPORT_QUERY (
'SELECT ma_sp, ten_sp, gia_ban FROM san_pham WHERE gia_ban < 100000',
'D:/bao_cao/san_pham_giam_gia.csv',
',', '"', 'UTF-8'
);
3. Nhập dữ liệu từ file (Import)
Tương tự như Export, quá trình Import yêu cầu bảng đích phải được tạo sẵn (có đầy đủ cột) trước khi chạy lệnh.
3.1. Nhập toàn bộ dữ liệu vào bảng (SYSCS_IMPORT_TABLE)
Cú pháp:
SQL
CALL SYSCS_UTIL.SYSCS_IMPORT_TABLE (
'TEN_SCHEMA', 'TEN_BANG', 'DUONG_DAN_FILE',
'DAU_PHAN_CACH_COT', 'DAU_BAO_CHUOI', 'ENCODING', THAY_THE
);
Tham số cuối cùng THAY_THE (Replace) nhận 2 giá trị:
-
0: Thêm dữ liệu mới vào bảng hiện tại (Append). -
1: Xóa sạch toàn bộ dữ liệu cũ trong bảng trước khi nhập dữ liệu từ file (Truncate & Insert).
Ví dụ: Nhập đè dữ liệu từ file CSV vào bảng khach_hang:
SQL
CALL SYSCS_UTIL.SYSCS_IMPORT_TABLE (
'APP', 'KHACH_HANG', 'D:/data/khach_hang_import.csv',
',', '"', 'UTF-8', 1
);
3.2. Nhập dữ liệu vào các cột chỉ định (SYSCS_IMPORT_DATA)
Nếu file CSV của bạn chỉ có 2 cột (ví dụ: ma_sp, gia_moi), nhưng bảng trong database lại có 5 cột, bạn phải chỉ định rõ luồng ánh xạ dữ liệu:
SQL
CALL SYSCS_UTIL.SYSCS_IMPORT_DATA (
'APP', 'SAN_PHAM',
'ma_sp, gia_ban', -- Danh sách cột trong CSDL sẽ nhận dữ liệu
'1, 2', -- Chỉ số cột tương ứng trong file CSV (tính từ 1)
'D:/data/cap_nhat_gia.csv',
',', '"', 'UTF-8', 0
);
4. Quản lý Import/Export bằng Java (JDBC)
Vì các công cụ này bản chất là các Stored Procedure, bạn có thể dễ dàng gọi chúng từ ứng dụng Java thông qua CallableStatement. Điều này cực kỳ hữu ích khi bạn muốn xây dựng tính năng "Xuất Excel/CSV" trên giao diện phần mềm.
Java
package com.hieu.derby.admin;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DerbyBulkTools {
public static void main(String[] args) {
String jdbcUrl = "jdbc:derby://localhost:1527/my_company_db";
try (Connection conn = DriverManager.getConnection(jdbcUrl)) {
System.out.println("Bắt đầu tiến trình Export dữ liệu...");
// Cú pháp gọi thủ tục hệ thống của Derby
String sqlExport = "CALL SYSCS_UTIL.SYSCS_EXPORT_QUERY(?, ?, ?, ?, ?)";
try (CallableStatement cstmt = conn.prepareCall(sqlExport)) {
// 1. Câu truy vấn SQL
cstmt.setString(1, "SELECT id, ho_ten, email FROM nhan_vien");
// 2. Đường dẫn file xuất ra (Phải nằm trên ổ cứng của Máy chủ)
cstmt.setString(2, "/var/backups/nhan_vien_export.csv");
// 3. Dấu phân cách cột
cstmt.setString(3, ",");
// 4. Dấu bao chuỗi
cstmt.setString(4, "\"");
// 5. Chuẩn mã hóa
cstmt.setString(5, "UTF-8");
cstmt.execute();
System.out.println("=> Xuất file CSV thành công!");
}
} catch (SQLException e) {
System.err.println("Lỗi thao tác dữ liệu: " + e.getMessage());
}
}
}
Lưu ý bảo mật đặc biệt quan trọng trong chế độ Network Server: Đường dẫn file trong lệnh Import/Export là đường dẫn vật lý trên máy chủ (Server) đang chạy Derby, KHÔNG PHẢI trên máy khách (Client). Máy chủ cũng cần phải có quyền đọc/ghi (Read/Write Permissions) vào thư mục được chỉ định.
5. Tổng kết
-
Các thủ tục Import/Export của Derby thao tác trực tiếp với Engine, bỏ qua tầng phân tích SQL, do đó tốc độ nạp dữ liệu nhanh hơn gấp nhiều lần so với việc chạy vòng lặp
INSERT. -
Định dạng phổ biến nhất được hỗ trợ là CSV (Comma-Separated Values).
-
Bạn có quyền quyết định thêm tiếp dữ liệu (
Replace = 0) hoặc xóa trắng bảng trước khi nhập (Replace = 1). -
Luôn sử dụng mã hóa
UTF-8để đảm bảo an toàn cho các ký tự có dấu.
Việc xuất dữ liệu ra file CSV rất tiện cho báo cáo, nhưng chưa đủ an toàn để bảo vệ hệ thống trước nguy cơ hỏng hóc phần cứng. Bài tiếp theo sẽ hướng dẫn kỹ năng sống còn của mọi quản trị viên hệ thống: Apache Derby Bài 35: Sao lưu (Backup) và Phục hồi (Restore) cơ sở dữ liệu.
All rights reserved