Pertama, penting untuk membedakan antara pernyataan yang disiapkan klien dan server.
Pernyataan yang Disiapkan Klien
Pernyataan yang disiapkan klien adalah pernyataan yang disiapkan "dicontohkan". Ini berarti bahwa string pernyataan SQL diberi token di sisi klien dan semua penampung diganti dengan nilai literal sebelum mengirim pernyataan ke server untuk dieksekusi. Pernyataan SQL lengkap dikirim ke server pada setiap eksekusi. Anda dapat menggunakan log umum untuk menyelidiki cara kerjanya. misalnya
kode berikut:
ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()
akan ditampilkan di log:
255 Query select 42
255 Query select 43
"Permintaan" menunjukkan bahwa, pada tingkat protokol, sebuah COM_QUERY
perintah dikirim dengan string pernyataan berikut.
Pernyataan yang Disiapkan Server
Pernyataan yang disiapkan server adalah pernyataan yang disiapkan "benar" yang berarti bahwa teks kueri dikirim ke server, diuraikan, dan placeholder dan informasi hasil dikembalikan ke klien. Inilah yang Anda dapatkan saat mengatur useServerPrepStmts=true
. String pernyataan hanya pernah dikirim ke server satu kali dengan COM_STMT_PREPARE
panggilan (didokumentasikan di sini
). Setiap eksekusi dilakukan dengan mengirimkan COM_STMT_EXECUTE
dengan pegangan pernyataan yang disiapkan dan nilai literal untuk menggantikan placeholder.
Untuk membedakan dengan contoh yang disiapkan klien, kita dapat menggunakan blok kode yang serupa (tetapi kali ini dengan pernyataan yang disiapkan server diaktifkan):
ps2=conn2.prepareStatement("select ?")
ps2.setInt(1, 42)
ps2.executeQuery()
ps2.setInt(1, 43)
ps2.executeQuery()
Dan log akan menunjukkan:
254 Prepare select ?
254 Execute select 42
254 Execute select 43
Anda dapat melihat bahwa pernyataan disiapkan sebelum dieksekusi. Log membantu kami dan menunjukkan pernyataan lengkap untuk eksekusi tetapi, pada kenyataannya, hanya nilai placeholder yang dikirim dari klien ke server untuk setiap eksekusi.
Caching Pernyataan yang Disiapkan
Banyak kumpulan koneksi akan menyimpan pernyataan yang disiapkan di cache di seluruh penggunaan koneksi yang berarti bahwa jika Anda memanggil conn.prepareStatement("select ?")
, itu akan mengembalikan PreparedStatement
yang sama instance pada panggilan berturut-turut dengan string pernyataan yang sama. Ini berguna untuk menghindari persiapan string yang sama di server berulang kali saat koneksi dikembalikan ke pool antar transaksi.
Opsi MySQL JDBC cachePrepStmts
akan men-cache pernyataan yang disiapkan dengan cara ini (pernyataan yang disiapkan klien dan server) serta menyimpan "persiapan" pernyataan dalam cache. Ada beberapa pernyataan di MySQL yang tidak dapat disiapkan di sisi server. Pengemudi akan mencoba menyiapkan pernyataan di server jika diyakini itu mungkin dan, jika persiapan gagal, kembali ke pernyataan yang disiapkan klien. Cek ini mahal karena membutuhkan perjalanan pulang pergi ke server. Opsi ini juga akan meng-cache hasil pemeriksaan ini.
Semoga membantu.