Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Sự khác biệt giữa Tuyên bố JDBC và Tuyên bố chuẩn bị

Mặc dù đúng là trong nhiều trường hợp, một câu lệnh SQL cơ bản sẽ hoàn thành công việc cho nhiều thay đổi hoặc truy vấn cơ sở dữ liệu, nhưng đây thường là một phương pháp hay nhất để tận dụng sự linh hoạt và lợi thế dành cho bạn bằng cách sử dụng PreparedStatements .

Sự khác biệt cơ bản giữa câu lệnh JDBC chuẩn và PreparedStatement được xác định rõ nhất bởi lợi ích rằng một PreparedStatement cung cấp cho bạn và ứng dụng của bạn. Dưới đây, chúng tôi sẽ xem xét ba ưu điểm cốt lõi của PreparedStatements qua các câu lệnh JDBC / SQL thông thường.

Ngăn chặn SQL Injection

Lợi ích đầu tiên của việc sử dụng PreparedStatement là bạn có thể tận dụng vô số .setXYZ() các phương thức, chẳng hạn như .setString() , cho phép mã của bạn tự động thoát khỏi các ký tự đặc biệt, chẳng hạn như dấu ngoặc kép trong câu lệnh SQL được truyền vào, ngăn chặn SQL injection luôn nguy hiểm tấn công.

Ví dụ:trong một câu lệnh SQL tiêu chuẩn, có thể điển hình là chèn các giá trị nội dòng trực tiếp với câu lệnh, như sau:

statement = "INSERT INTO books (title, primary_author, published_date) VALUES ('" + book.getTitle() + "', '" + book.getPrimaryAuthor() + "', '" + new Timestamp(book.getPublishedDate().getTime()) + "'";

Điều này sẽ buộc bạn phải thực thi mã của riêng mình để ngăn chặn việc đưa vào SQL bằng cách thoát dấu ngoặc kép và các ký tự đặc biệt khác khỏi các giá trị được chèn.

Ngược lại, một PreparedStatement có thể được gọi như sau, sử dụng .setXYZ() phương pháp chèn giá trị với ký tự tự động thoát trong khi thực thi phương thức:

ps = connection.prepareStatement("INSERT INTO books (title, primary_author, published_date) VALUES (?, ?, ?)");
ps.setString(1, book.getTitle());
ps.setString(2, book.getPrimaryAuthor());
ps.setTimestamp(3, new Timestamp(book.getPublishedDate().getTime()));
ps.executeUpdate();

Pre-Compilation

Một lợi ích khác của PreparedStatement là bản thân SQL đã được pre-compiled một lần duy nhất và sau đó được hệ thống giữ lại trong bộ nhớ, thay vì được biên dịch mỗi lần câu lệnh được gọi. Điều này cho phép thực thi nhanh hơn, đặc biệt khi PreparedStatement được sử dụng cùng với batches , cho phép bạn thực thi một chuỗi (hoặc batches ) của các câu lệnh SQL cùng một lúc trong một kết nối cơ sở dữ liệu.

Ví dụ, ở đây chúng tôi có một hàm chấp nhận một List của những cuốn sách. Đối với mỗi book trong danh sách, chúng tôi muốn thực thi một INSERT nhưng chúng tôi sẽ thêm tất cả chúng vào một loạt PreparedStatements và thực hiện tất cả trong một cú ngã:

public void createBooks(List<Entity> books) throws SQLException {
  try (
    Connection connection = dataSource.getConnection();
    PreparedStatement ps = connection.prepareStatement("INSERT INTO books (title, primary_author, published_date) VALUES (?, ?, ?)");
  ) {
    for (Entity book : books) {
      ps.setString(1, book.getTitle());
      ps.setString(2, book.getPrimaryAuthor());
      ps.setTimestamp(3, new Timestamp(book.getPublishedDate().getTime()));

      ps.addBatch();
    }
    ps.executeBatch();
  }
}

Chèn các kiểu dữ liệu bất thường trong câu lệnh SQL

Ưu điểm cuối cùng của PreparedStatements mà chúng tôi sẽ đề cập đến là khả năng chèn các kiểu dữ liệu bất thường vào chính câu lệnh SQL, chẳng hạn như Timestamp , InputStream và nhiều hơn nữa.

Ví dụ:chúng ta có thể sử dụng PreparedStatement để thêm ảnh bìa vào hồ sơ sách của chúng tôi bằng cách sử dụng .setBinaryStream() phương pháp:

ps = connection.prepareStatement("INSERT INTO books (cover_photo) VALUES (?)");
ps.setBinaryStream(1, book.getPhoto());
ps.executeUpdate();

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Phương pháp tự động hóa Azure

  2. Bạn không thích trình kích hoạt cơ sở dữ liệu? Bạn chỉ không biết cách làm việc với chúng!

  3. DELETE VS DROP trong SQL

  4. Cách kết nối cơ sở dữ liệu với Amazon VPC

  5. Hướng dẫn về các chức năng của PubNub