Pernyataan Disiapkan adalah versi Pernyataan yang sedikit lebih kuat, dan harus selalu setidaknya secepat dan mudah ditangani sebagai Pernyataan.
Pernyataan Disiapkan dapat parametrized
Sebagian besar basis data relasional menangani permintaan JDBC / SQL dalam empat langkah:
- Parsing kueri SQL yang masuk
- Kompilasi permintaan SQL
- Merencanakan / mengoptimalkan jalur akuisisi data
- Jalankan permintaan / perolehan dan pengembalian data yang dioptimalkan
Pernyataan akan selalu diproses melalui empat langkah di atas untuk setiap permintaan SQL yang dikirim ke database. Pernyataan Disiapkan pra-eksekusi langkah (1) - (3) dalam proses eksekusi di atas. Jadi, ketika membuat Pernyataan Disiapkan, beberapa pra-optimasi dilakukan segera. Efeknya adalah untuk mengurangi beban pada mesin database pada waktu eksekusi.
Sekarang pertanyaan saya adalah - "Apakah ada keuntungan lain dari menggunakan Pernyataan Disiapkan?"
Jawaban:
Keuntungan a
PreparedStatement
:Precompilation dan caching sisi-DB dari pernyataan SQL mengarah pada keseluruhan eksekusi yang lebih cepat dan kemampuan untuk menggunakan kembali pernyataan SQL yang sama dalam batch .
Pencegahan serangan injeksi SQL secara otomatis dengan menghilangkan tanda kutip dan karakter khusus lainnya. Perhatikan bahwa ini mengharuskan Anda menggunakan salah satu dari
PreparedStatement
setXxx()
metode untuk menetapkan nilaidan dengan demikian tidak menyejajarkan nilai-nilai dalam string SQL dengan string-concatenating.
Meringankan pengaturan benda Jawa non-standar dalam string SQL, misalnya
Date
,Time
,Timestamp
,BigDecimal
,InputStream
(Blob
) danReader
(Clob
). Pada sebagian besar tipe tersebut, Anda tidak dapat "hanya" melakukantoString()
seperti yang Anda lakukan secara sederhanaStatement
. Anda bahkan bisa memperbaiki semuanya untuk menggunakanPreparedStatement#setObject()
di dalam loop seperti yang ditunjukkan dalam metode utilitas di bawah ini:Yang bisa digunakan seperti di bawah ini:
sumber
Statement
, tetapi mungkin layak untuk diuji.Mereka sudah dikompilasi sebelumnya (sekali), jadi lebih cepat untuk eksekusi SQL dinamis berulang (di mana parameter berubah)
Caching pernyataan basis data meningkatkan kinerja eksekusi DB
Pangkalan data menyimpan cache rencana eksekusi untuk pernyataan yang dieksekusi sebelumnya. Ini memungkinkan mesin basis data untuk menggunakan kembali rencana untuk pernyataan yang telah dieksekusi sebelumnya. Karena PreparedStatement menggunakan parameter, setiap kali dieksekusi muncul sebagai SQL yang sama, database dapat menggunakan kembali rencana akses sebelumnya, mengurangi pemrosesan. Pernyataan "inline" parameter ke string SQL dan tidak muncul sebagai SQL yang sama dengan DB, mencegah penggunaan cache.
Protokol komunikasi biner berarti lebih sedikit bandwidth dan lebih cepat melakukan panggilan ke server DB
Pernyataan yang disiapkan biasanya dieksekusi melalui protokol biner non-SQL. Ini berarti bahwa ada lebih sedikit data dalam paket, sehingga komunikasi ke server lebih cepat. Sebagai aturan praktis operasi jaringan adalah urutan besarnya lebih lambat dari operasi disk yang urutan besarnya lebih lambat dari operasi CPU dalam memori. Oleh karena itu, setiap pengurangan jumlah data yang dikirim melalui jaringan akan memiliki efek yang baik pada kinerja keseluruhan.
Mereka melindungi terhadap injeksi SQL, dengan menghindari teks untuk semua nilai parameter yang disediakan.
Mereka memberikan pemisahan yang lebih kuat antara kode kueri dan nilai parameter (dibandingkan dengan string SQL gabungan), meningkatkan keterbacaan dan membantu pengelola kode dengan cepat memahami input dan output dari kueri.
Di java, bisa memanggil getMetadata () dan getParameterMetadata () untuk merefleksikan bidang hasil set dan bidang parameter, masing-masing
Di java, secara cerdas menerima objek java sebagai tipe parameter melalui setObject, setBoolean, setByte, setDate, setDouble, setDloat, setFloat, setInt, setLong, setShort, setTimestamp - ini dikonversi ke dalam format tipe JDBC yang dapat dipahami oleh DB (tidak hanya toString () format).
Di java, menerima SQL ARRAYs, sebagai tipe parameter melalui metode setArray
Di java, masing-masing menerima CLOBs, BLOBs, OutputStreams, dan Pembaca sebagai parameter "feed" melalui setClob / setNClob, setBlob, setBinaryStream, setCharacterStream / setAsciiStream / metode setNCharacterStream, secara berurutan
Di java, memungkinkan nilai-nilai spesifik DB untuk diatur untuk SQL DATALINK, SQL ROWID, SQL XML, dan NULL melalui setURL, setRowId, setSQLXML, dan metode setNull
Di java, mewarisi semua metode dari Pernyataan. Itu mewarisi metode addBatch, dan juga memungkinkan satu set nilai parameter yang akan ditambahkan agar sesuai dengan set perintah SQL batch melalui metode addBatch.
Di java, jenis khusus PreparedStatement (subclass CallableStatement) memungkinkan prosedur tersimpan untuk dieksekusi - mendukung kinerja tinggi, enkapsulasi, pemrograman prosedural dan SQL, administrasi DB / pemeliharaan / tweaker logika, dan penggunaan logika & fitur DB eksklusif
sumber
Connection.createStatement
danConnection.prepareStatement
. Desain ini memaksa Anda untuk bekerja melawan antarmuka sehingga Anda tidak perlu tahu kelas implementasi spesifik dan untuk menghindari penggabungan erat yang tidak perlu dengan kelas implementasi tersebut. Semua dijelaskan dengan contoh dalam Java jdbc docs & Java docs. :)PreparedStatement
adalah pertahanan yang sangat baik (tapi tidak mudah) dalam mencegah serangan injeksi SQL . Mengikat nilai parameter adalah cara yang baik untuk menjaga terhadap "Bobby Tables kecil" melakukan kunjungan yang tidak diinginkan.sumber
ORDER BY
) dan / atau konstanta numerik di tempat-tempat tertentu (thinkLIMIT
,OFFSET
dan solusi pagination lainnya), sehingga ini dapat diserang oleh injeksi SQL, bahkan ketika Pernyataan dan parameterisasi Disiapkan digunakan di mana pun bisa jadi.Beberapa manfaat dari PreparedStatement atas Pernyataan adalah:
Baca lebih lanjut tentang masalah injeksi SQL di http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example
sumber
tidak banyak yang ditambahkan,
1 - jika Anda ingin menjalankan kueri dalam satu lingkaran (lebih dari 1 kali), pernyataan yang disiapkan dapat lebih cepat, karena optimasi yang Anda sebutkan.
2 - kueri parameterisasi adalah cara yang baik untuk menghindari SQL Injection. Permintaan parameter hanya tersedia di PreparedStatement.
sumber
Pernyataan statis dan statment yang disiapkan dinamis.
Pernyataan cocok untuk DDL dan menyiapkan statment untuk DML.
Pernyataan lebih lambat sementara pernyataan yang disiapkan lebih cepat.
lebih banyak perbedaan (diarsipkan)
sumber
Tidak dapat melakukan CLOB dalam Pernyataan.
Dan: (OraclePreparedStatement) ps
sumber
Dikutip oleh mattjames
sumber
sql injeksi diabaikan oleh pernyataan yang disiapkan sehingga keamanan ditingkatkan dalam pernyataan yang disiapkan
sumber
sumber
Pernyataan akan digunakan untuk mengeksekusi pernyataan SQL statis dan tidak dapat menerima parameter input.
PreparedStatement akan digunakan untuk mengeksekusi pernyataan SQL berkali-kali secara dinamis. Ini akan menerima parameter input.
sumber
Karakteristik lain dari Permintaan Disiapkan atau Parameter: Referensi diambil dari artikel ini.
Pernyataan ini adalah salah satu fitur dari sistem database di mana pernyataan SQL yang sama dijalankan berulang kali dengan efisiensi tinggi. Pernyataan yang disiapkan adalah satu jenis Templat dan digunakan oleh aplikasi dengan parameter yang berbeda.
Templat pernyataan disiapkan dan dikirim ke sistem basis data dan sistem basis data melakukan parsing, kompilasi, dan optimisasi pada templat ini dan menyimpannya tanpa menjalankannya.
Beberapa parameter seperti, di mana klausa tidak dilewati selama pembuatan template aplikasi nanti, mengirim parameter ini ke sistem database dan sistem database menggunakan template dari SQL Statement dan dijalankan sesuai permintaan.
Pernyataan yang disiapkan sangat berguna terhadap SQL Injection karena aplikasi dapat menyiapkan parameter menggunakan berbagai teknik dan protokol.
Ketika jumlah data meningkat dan indeks sering berubah pada waktu itu, Laporan yang Disiapkan mungkin gagal karena dalam situasi ini memerlukan rencana kueri baru.
sumber
Statement
antarmuka mengeksekusi pernyataan SQL statis tanpa parameterPreparedStatement
interface (extending Statement) mengeksekusi pernyataan SQL yang dikompilasi dengan / tanpa parameterEfisien untuk eksekusi berulang
Ini dikompilasi sehingga lebih cepat
sumber
Jangan bingung: ingat saja
sumber
Saya mengikuti semua jawaban dari pertanyaan ini untuk mengubah kode lama bekerja menggunakan -
Statement
(tetapi memiliki SQL Suntikan) untuk solusi menggunakanPreparedStatement
dengan kode yang jauh lebih lambat karena pemahaman semantik sekitarStatement.addBatch(String sql)
& kurangPreparedStatement.addBatch()
.Jadi saya daftar skenario saya di sini sehingga orang lain tidak membuat kesalahan yang sama.
Skenario saya adalah
Jadi dalam kode di atas, saya memiliki ribuan pertanyaan yang berbeda, semua ditambahkan ke pernyataan yang sama dan kode ini bekerja lebih cepat karena pernyataan yang tidak di-cache bagus & kode ini jarang dieksekusi di app.
Sekarang untuk memperbaiki Suntikan SQL, saya mengubah kode ini menjadi,
Jadi Anda lihat, saya mulai membuat ribuan
PreparedStatement
objek & akhirnya tidak dapat memanfaatkan batching karena skenario saya menuntut - ada ribuan permintaan UPDATE atau INSERT & semua pertanyaan ini kebetulan berbeda.Memperbaiki injeksi SQL adalah wajib tanpa biaya penurunan kinerja dan saya tidak berpikir itu mungkin terjadi
PreparedStatement
dalam skenario ini.Juga, ketika Anda menggunakan fasilitas batching inbuilt, Anda harus khawatir tentang hanya menutup satu Pernyataan tetapi dengan pendekatan Daftar ini, Anda perlu menutup pernyataan sebelum digunakan kembali, Menggunakan Kembali PreparedStatement
sumber