Database
 sql >> база данни >  >> RDS >> Database

Разликата между JDBC изявление и подготвено изявление

Въпреки че е вярно, че в много случаи основният SQL израз ще свърши работата за много промени в базата данни или заявки, това често е най-добра практика за да се възползвате от гъвкавостта и предимствата, предоставени ви с помощта на PreparedStatements .

Основните разлики между стандартен JDBC израз и PreparedStatement се определят най-добре от ползите че PreparedStatement предоставя на вас и вашето приложение. По-долу ще разгледаме трите основни предимства на PreparedStatements над обикновени JDBC/SQL оператори.

Предотвратяване на инжектиране на SQL

Първата полза от използването на PreparedStatement е, че можете да се възползвате от множеството .setXYZ() методи, като .setString() , което позволява на вашия код автоматично да избягва специални символи като кавички в рамките на предадения в SQL израз, предотвратявайки винаги опасното SQL injection атака.

Например, в стандартен SQL израз може да е типично да се вмъкнат стойности директно в рамките на израза, като така:

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

Това ще ви принуди да изпълните свой собствен код, за да предотвратите SQL инжекции, като избягвате кавички и други специални знаци от вмъкнатите стойности.

Обратно, PreparedStatement може да бъде извикан както следва, като се използва .setXYZ() методи за вмъкване на стойности с автоматично екраниране на символи по време на изпълнение на метода:

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

Предварителна компилация

Друго предимство на PreparedStatement е, че самият SQL е pre-compiled един път и след това се запазва в паметта от системата, вместо да се компилира всеки път, когато операторът се извиква. Това позволява по-бързо изпълнение, особено когато PreparedStatement се използва във връзка с batches , които ви позволяват да изпълните серия (или batch ) на SQL изрази наведнъж по време на една връзка с база данни.

Например, тук имаме функция, която приема List на книги. За всяка book в списъка искаме да изпълним INSERT изявление, но ще ги добавим всички към партида от PreparedStatements и да ги изпълни с един замах:

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

Вмъкване на необичайни типове данни в SQL изявление

Последното предимство на PreparedStatements което ще покрием е възможността за вмъкване на необичайни типове данни в самия SQL израз, като Timestamp , InputStream , и много други.

Например, можем да използваме PreparedStatement за да добавите снимка на корицата към записа на нашата книга с помощта на .setBinaryStream() метод:

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. Как да сортирате в SQL

  2. Преодоляване на пропастта в Azure:управлявани екземпляри

  3. Как да изтриете ограничение за външен ключ в SQL

  4. Как да изчислим абсолютна стойност в SQL

  5. Свързване на Snowflake DB &IRI Workbench