Database
 sql >> Baza danych >  >> RDS >> Database

Różnica między oświadczeniem JDBC a przygotowanym oświadczeniem

Chociaż prawdą jest, że w wielu przypadkach podstawowe polecenie SQL wykona zadanie dla wielu zmian lub zapytań w bazie danych, często jest to najlepsza praktyka aby wykorzystać elastyczność i korzyści, jakie daje Ci użycie PreparedStatements .

Podstawowe różnice między standardową instrukcją JDBC a PreparedStatement najlepiej określają korzyści że PreparedStatement zapewnia Tobie i Twojej aplikacji. Poniżej przeanalizujemy trzy podstawowe zalety PreparedStatements nad zwykłymi instrukcjami JDBC/SQL.

Zapobieganie wstrzykiwaniu SQL

Pierwsza korzyść z używania PreparedStatement możesz skorzystać z mnogości .setXYZ() metody, takie jak .setString() , który pozwala Twojemu kodowi na automatyczne unikanie znaków specjalnych, takich jak cytaty w ramach przekazanej instrukcji SQL, zapobiegając zawsze niebezpiecznemu SQL injection atak.

Na przykład w standardowej instrukcji SQL typowe może być wstawianie wartości bezpośrednio w instrukcji, na przykład:

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

To zmusiłoby Cię do wykonania własnego kodu, aby zapobiec wstrzykiwaniu SQL poprzez unikanie cudzysłowów i innych znaków specjalnych z wstawionych wartości.

I odwrotnie, PreparedStatement można wywołać w następujący sposób, używając .setXYZ() metody do wstawiania wartości z automatycznym unikaniem znaków podczas wykonywania metody:

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();

Wstępna kompilacja

Kolejna zaleta PreparedStatement jest to, że sam SQL jest pre-compiled jednorazowo, a następnie zachowywane w pamięci przez system, zamiast być kompilowane za każdym razem, gdy instrukcja jest wywoływana. Pozwala to na szybsze wykonanie, szczególnie gdy PreparedStatement jest używany w połączeniu z batches , które umożliwiają wykonanie serii (lub batch ) wszystkich instrukcji SQL jednocześnie podczas jednego połączenia z bazą danych.

Na przykład tutaj mamy funkcję, która akceptuje List książek. Dla każdej book na liście chcemy wykonać INSERT oświadczenie, ale zamierzamy dodać je wszystkie do partii PreparedStatements i wykonaj je wszystkie za jednym zamachem:

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();
  }
}

Wstawianie nieprawidłowych typów danych w instrukcji SQL

Ostatnia zaleta PreparedStatements omówimy to możliwość wstawiania nieprawidłowych typów danych do samego wyrażenia SQL, takich jak Timestamp , InputStream i wiele innych.

Na przykład możemy użyć PreparedStatement aby dodać zdjęcie na okładkę do naszego rekordu książki za pomocą .setBinaryStream() metoda:

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. Łączenie F# z Salesforce.com

  2. Analiza operacyjna w czasie rzeczywistym i indeks nieklastrowanego magazynu kolumn

  3. Różne plany dla identycznych serwerów

  4. Podstawy sys.dm_exec_requests

  5. SCD typu 2