Saya tidak ingat begitu saja apakah Hibernate benar-benar menyimpan instance PreparedStatement itu sendiri, atau bergantung pada penyedia koneksi untuk menggunakannya kembali. (Pemindaian cepat BatcherImpl menyarankan untuk menggunakan kembali PreparedStatement terakhir jika menjalankan SQL yang sama beberapa kali berturut-turut)
Saya pikir poin yang coba dibuat oleh dokumentasi c3p0 adalah bahwa untuk banyak driver JDBC, PreparedStatement tidak berguna:beberapa driver akan berakhir hanya dengan menyambungkan parameter di sisi klien dan kemudian meneruskan pernyataan SQL yang dibuat ke database. . Untuk driver ini, PreparedStatements sama sekali tidak menguntungkan, dan upaya apa pun untuk menggunakannya kembali akan sia-sia. (FAQ Postgresql JDBC mengatakan ini adalah kasus untuk Postgresql sebelum protokol sever versi 3 dan ada informasi lebih rinci dalam dokumentasi).
Untuk driver yang menangani PreparedStatements dengan bermanfaat, kemungkinan masih perlu untuk benar-benar menggunakan kembali instance PreparedStatement untuk mendapatkan manfaat apa pun. Misalnya jika driver mengimplementasikan:
- Connection.prepareStatement(sql) - buat pernyataan sisi server
- PreparedStatement.execute(..) dll - jalankan pernyataan sisi server itu
- PreparedStatement.close() - membatalkan alokasi pernyataan sisi server
Mengingat hal ini, jika aplikasi selalu membuka pernyataan yang telah disiapkan, mengeksekusinya sekali dan kemudian menutupnya lagi, masih tidak ada manfaat; pada kenyataannya, ini mungkin lebih buruk karena sekarang ada kemungkinan lebih banyak perjalanan pulang pergi. Jadi aplikasi harus bergantung pada instance PreparedStatement. Tentu saja, ini mengarah ke masalah lain:jika aplikasi terlalu banyak hang, dan setiap pernyataan sisi server menghabiskan beberapa sumber daya, maka ini dapat menyebabkan masalah sisi server. Dalam kasus di mana seseorang menggunakan JDBC secara langsung, ini mungkin dikelola dengan baik - beberapa pernyataan diketahui dapat digunakan kembali dan karenanya disiapkan; beberapa tidak dan hanya menggunakan contoh Pernyataan sementara saja. (Ini melewatkan manfaat lain dari pernyataan yang disiapkan:menangani pelolosan argumen)
Jadi inilah mengapa c3p0 dan kumpulan koneksi lainnya juga telah menyiapkan cache pernyataan - ini memungkinkan kode aplikasi untuk menghindari berurusan dengan semua ini. Pernyataan biasanya disimpan di beberapa kumpulan LRU terbatas, jadi pernyataan umum menggunakan kembali instance PreparedStatement.
Potongan terakhir dari teka-teki adalah bahwa pengemudi JDBC sendiri mungkin memutuskan untuk menjadi pintar dan melakukan ini; dan server sendiri juga dapat memutuskan untuk menjadi pintar dan mendeteksi klien yang mengirimkan pernyataan yang secara struktural mirip dengan pernyataan sebelumnya.
Mengingat bahwa Hibernate sendiri tidak menyimpan cache instance PreparedStatement, Anda harus meminta c3p0 melakukannya untuk mendapatkan manfaatnya. (Yang harus dikurangi overhead untuk pernyataan umum karena menggunakan kembali paket yang di-cache). Jika c3p0 tidak men-cache pernyataan yang disiapkan, maka driver hanya akan melihat aplikasi menyiapkan pernyataan, mengeksekusinya, dan kemudian menutupnya kembali. Sepertinya driver JDBC memiliki pengaturan "ambang" untuk menghindari overhead server persiapan/eksekusi jika aplikasi selalu melakukan ini. Jadi, ya, Anda harus memiliki c3p0 melakukan cache pernyataan.
Semoga membantu, maaf agak panjang lebar. Jawabannya adalah ya .