Po pierwsze, ważne jest, aby odróżnić wyciągi przygotowane przez klienta i serwer.
Oświadczenia przygotowane przez klienta
Wyciągi przygotowane przez klienta są „emulowanymi” wyciągami przygotowanymi. Oznacza to, że ciąg instrukcji SQL jest tokenizowany po stronie klienta, a wszelkie symbole zastępcze są zastępowane wartościami dosłownymi przed wysłaniem instrukcji do serwera w celu wykonania. Kompletna instrukcja SQL jest wysyłana do serwera przy każdym wykonaniu. Możesz użyć dziennika ogólnego, aby sprawdzić, jak to działa. np.
następujący kod:
ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()
pokaże się w dzienniku:
255 Query select 42
255 Query select 43
„Zapytanie” wskazuje, że na poziomie protokołu COM_QUERY
polecenie jest wysyłane z następującym ciągiem instrukcji.
Wyciągi przygotowane przez serwer
Przygotowane instrukcje serwera są „prawdziwymi” przygotowanymi instrukcjami, co oznacza, że tekst zapytania jest wysyłany do serwera, analizowany, a informacje zastępcze i wyniki są zwracane do klienta. Oto, co otrzymujesz, ustawiając useServerPrepStmts=true
. Ciąg instrukcji jest wysyłany do serwera tylko raz z kodem COM_STMT_PREPARE
zadzwoń (udokumentowane tutaj
). Każde wykonanie jest wykonywane przez wysłanie COM_STMT_EXECUTE
z przygotowanym uchwytem instrukcji i wartościami dosłownymi zastępującymi symbole zastępcze.
W przeciwieństwie do przykładu przygotowanego przez klienta, możemy użyć podobnego bloku kodu (ale tym razem z włączonymi instrukcjami przygotowanymi przez serwer):
ps2=conn2.prepareStatement("select ?")
ps2.setInt(1, 42)
ps2.executeQuery()
ps2.setInt(1, 43)
ps2.executeQuery()
A dziennik pokazywałby:
254 Prepare select ?
254 Execute select 42
254 Execute select 43
Widać, że instrukcja jest przygotowywana przed wykonaniem. Dziennik wyświadcza nam przysługę i pokazuje pełną instrukcję wykonania, ale w rzeczywistości tylko wartości zastępcze są wysyłane od klienta do serwera dla każdego wykonania.
Buforowanie przygotowanych instrukcji
Wiele pul połączeń przechowuje w pamięci podręcznej przygotowane instrukcje w różnych zastosowaniach połączenia, co oznacza, że jeśli wywołasz conn.prepareStatement("select ?")
, zwróci ten sam PreparedStatement
wystąpienie w kolejnych wywołaniach z tym samym ciągiem instrukcji. Jest to przydatne, aby uniknąć wielokrotnego przygotowywania tego samego ciągu na serwerze, gdy połączenia są zwracane do puli między transakcjami.
Opcja MySQL JDBC cachePrepStmts
w ten sposób buforuje przygotowane oświadczenia (zarówno przygotowane przez klienta, jak i serwer) oraz buforuje „przygotowalność” oświadczenia. W MySQL jest kilka instrukcji, których nie można przygotować po stronie serwera. Sterownik spróbuje przygotować instrukcję na serwerze, jeśli uzna, że jest to możliwe, a jeśli przygotowanie się nie powiedzie, powróci do instrukcji przygotowanej przez klienta. Ta kontrola jest kosztowna, ponieważ wymaga podróży w obie strony na serwer. Ta opcja spowoduje również buforowanie wyniku tego sprawdzenia.
Mam nadzieję, że to pomoże.