Vấn đề: Escape backslash khi chèn dữ liệu qua JDBC
Khi làm việc với chuỗi chứa ký tự backslash (\) trong MySQL qua JDBC, việc nối chuỗi SQL trực tiếp dễ gây lỗi cú pháp hoặc tiêm SQL. Giải pháp an toàn và hiệu quả là sử dụng PreparedStatement.
Giải pháp: Sử dụng PreparedStatement
PreparedStatement tự động xử lý escape cho các ký tự đặc biệt, bao gồm backslash, nháy đơn, nháy kép, v.v. Nó cũng ngăn chặn tấn công SQL Injection.
1. Tạo bảng mẫu
CREATE TABLE DemoTable (
ClientId INT,
ClientName VARCHAR(20),
ClientAge INT
);
2. Mã Java sử dụng PreparedStatement
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class EscapeBackslashesDemo {
public static void main(String[] args) {
Connection con = null;
PreparedStatement ps = null;
try {
// Kết nối database (thay đổi URL, user, password cho phù hợp)
con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/web?useSSL=false",
"root", "123456"
);
// Câu lệnh SQL với placeholder (?)
String query = "INSERT INTO DemoTable(ClientId, ClientName, ClientAge) VALUES (?, ?, ?)";
ps = con.prepareStatement(query);
// Gán giá trị cho các tham số
ps.setInt(1, 1001);
ps.setString(2, "David Miller"); // Giá trị có thể chứa backslash
ps.setInt(3, 35);
// Thực thi
ps.executeUpdate();
System.out.println("Một hàng đã được chèn.....");
} catch (Exception e) {
e.printStackTrace();
} finally {
// Đóng tài nguyên (nên dùng try-with-resources trong Java 7+)
try { if (ps != null) ps.close(); } catch (Exception ignored) {}
try { if (con != null) con.close(); } catch (Exception ignored) {}
}
}
}
3. Kết quả kiểm tra
SELECT * FROM DemoTable;
+----------+--------------+-----------+
| ClientId | ClientName | ClientAge |
+----------+--------------+-----------+
| 1001 | David Miller | 35 |
+----------+--------------+-----------+
Tại sao PreparedStatement tốt hơn?
- An toàn: Tự động escape ký tự đặc biệt, ngăn SQL Injection.
- Hiệu suất: Cơ sở dữ liệu có thể cache kế hoạch thực thi cho câu lệnh tham số hóa.
- Đọc được: Tách biệt logic SQL và dữ liệu, code rõ ràng hơn.
- Hỗ trợ kiểu dữ liệu:
setInt,setString,setDate, v.v. xử lý chuyển đổi kiểu tự động.
Lưu ý thêm
- Luôn đóng
Connection,PreparedStatement,ResultSettrong khốifinallyhoặc dùngtry-with-resources. - Với MySQL, thêm tham số
useSSL=falsenếu không dùng SSL (phiên bản driver mới có thể không cần). - Nếu dữ liệu chứa backslash thực sự (ví dụ đường dẫn Windows
C:\Users),PreparedStatementsẽ lưu chính xác chuỗi đó mà không cần escape thủ công.