sql >> Databáze >  >> RDS >> Database

Rozdíl mezi prohlášením JDBC a připraveným prohlášením

I když je pravda, že v mnoha případech základní příkaz SQL vykoná práci u mnoha změn v databázi nebo dotazů, často jde o nejlepší postup abyste využili flexibilitu a výhody, které vám nabízí používání PreparedStatements .

Primární rozdíly mezi standardním příkazem JDBC a PreparedStatement jsou nejlépe definovány podle výhod že PreparedStatement poskytuje vám a vaší aplikaci. Níže prozkoumáme tři hlavní výhody PreparedStatements přes běžné příkazy JDBC/SQL.

Prevence vkládání SQL

První výhoda použití PreparedStatement můžete využít množství .setXYZ() metody, jako je .setString() , což umožňuje vašemu kódu automaticky uniknout speciálním znakům, jako jsou uvozovky v předávaném příkazu SQL, čímž se zabrání vždy nebezpečnému SQL injection útok.

Například ve standardním příkazu SQL může být typické vkládat hodnoty přímo do řádku příkazu, například takto:

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

To by vás donutilo spustit svůj vlastní kód, abyste zabránili injekcím SQL escapováním uvozovek a dalších speciálních znaků z vložených hodnot.

Naopak PreparedStatement lze vyvolat následovně pomocí .setXYZ() metody pro vkládání hodnot s automatickým escapováním znaků během provádění 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();

Předkompilace

Další výhoda PreparedStatement je, že samotný SQL je pre-compiled jednou a poté uchován v paměti systémem, spíše než aby byl kompilován pokaždé, když je příkaz volán. To umožňuje rychlejší provádění, zvláště když PreparedStatement se používá ve spojení s batches , které vám umožní spustit sérii (nebo batch ) příkazů SQL najednou během jednoho připojení k databázi.

Například zde máme funkci, která přijímá List knih. Pro každou book v seznamu chceme provést INSERT příkaz, ale všechny je přidáme do dávky PreparedStatements a všechny je jedním šmahem popravit:

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

Vložení abnormálních datových typů do příkazu SQL

Poslední výhoda PreparedStatements kterou se budeme zabývat, je schopnost vkládat abnormální datové typy do samotného příkazu SQL, jako je Timestamp , InputStream a mnoho dalších.

Můžeme například použít PreparedStatement k přidání titulní fotografie k našemu záznamu knihy pomocí .setBinaryStream() metoda:

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

  1. VLDB ve věku 20 let:Budete potřebovat větší…

  2. SQLSTATE[HY093]:Neplatné číslo parametru:parametr nebyl definován

  3. Laravel OrderPodle počtu vztahu

  4. Používejte relační databáze MySQL na Debianu 6 (Squeeze)