sql >> データベース >  >> RDS >> Database

JDBCステートメントとプリペアドステートメントの違い

    多くの場合、基本的なSQLステートメントで多くのデータベースの変更やクエリを実行できることは事実ですが、多くの場合、ベストプラクティスです。 PreparedStatementsを使用することで得られる柔軟性と利点を活用するため 。

    標準のJDBCステートメントとPreparedStatementの主な違い メリットによって最もよく定義されます そのPreparedStatement あなたとあなたのアプリケーションを提供します。以下では、PreparedStatementsの3つの主要な利点を検証します。 通常の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のもう1つの利点 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の最後の利点 ここで取り上げるのは、Timestampなどの異常なデータ型をSQLステートメント自体に挿入する機能です。 、InputStream 、その他多数。

    たとえば、PreparedStatementを使用できます .setBinaryStream()を使用して、本のレコードにカバー写真を追加します 方法:

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

    1. 垂直出力を使用してSQLiteクエリ結果を表示する

    2. MySQLクエリからn番目のレコードを返す

    3. SQL Serverとは何ですか?

    4. データベースセキュリティのためのPercona監査ログプラグインの使用