Nejprve je důležité rozlišovat mezi příkazy připravenými klientem a serverem.
Prohlášení připravená klientem
Klientem připravené výpisy jsou „emulované“ připravené výpisy. To znamená, že řetězec příkazu SQL je tokenizován na straně klienta a všechny zástupné symboly jsou nahrazeny doslovnými hodnotami před odesláním příkazu na server k provedení. Při každém spuštění je na server odeslán úplný příkaz SQL. Chcete-li zjistit, jak to funguje, můžete použít obecný protokol. např.
následující kód:
ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()
se zobrazí v protokolu:
255 Query select 42
255 Query select 43
"Dotaz" označuje, že na úrovni protokolu COM_QUERY
příkaz je odeslán s následujícím řetězcem příkazu.
Prohlášení připravená serverem
Serverem připravené příkazy jsou "pravdivé" připravené příkazy, což znamená, že text dotazu je odeslán na server, analyzován a zástupný symbol a informace o výsledku jsou vráceny klientovi. To je to, co získáte, když nastavíte useServerPrepStmts=true
. Řetězec příkazu je vždy odeslán na server pouze jednou s COM_STMT_PREPARE
hovor (zdokumentováno zde
). Každé provedení se provádí odesláním COM_STMT_EXECUTE
s připraveným popisovačem příkazu a doslovnými hodnotami, které mají nahradit zástupné symboly.
Na rozdíl od příkladu připraveného klientem můžeme použít podobný blok kódu (tentokrát se zapnutými příkazy připravenými serverem):
ps2=conn2.prepareStatement("select ?")
ps2.setInt(1, 42)
ps2.executeQuery()
ps2.setInt(1, 43)
ps2.executeQuery()
A protokol by ukázal:
254 Prepare select ?
254 Execute select 42
254 Execute select 43
Můžete vidět, že příkaz je připraven před provedením. Protokol nám dělá laskavost a zobrazuje kompletní příkaz pro provedení, ale ve skutečnosti jsou z klienta na server pro každé provedení odesílány pouze zástupné hodnoty.
Ukládání připravených výpisů do mezipaměti
Mnoho fondů připojení ukládá do mezipaměti připravené příkazy pro různá použití připojení, což znamená, že pokud zavoláte conn.prepareStatement("select ?")
, vrátí stejný PreparedStatement
instance na po sobě jdoucích voláních se stejným řetězcem příkazů. To je užitečné, abyste se vyhnuli opakované přípravě stejného řetězce na serveru, když se spojení mezi transakcemi vrací do fondu.
Možnost MySQL JDBC cachePrepStmts
bude tímto způsobem ukládat do mezipaměti připravené příkazy (příkazy připravené klientem i serverem) a také ukládat do mezipaměti "připravitelnost" příkazu. V MySQL jsou některé příkazy, které nelze připravit na straně serveru. Ovladač se pokusí připravit výpis na serveru, pokud se domnívá, že je to možné, a pokud se příprava nezdaří, vrátí se k výpisu připravenému klientem. Tato kontrola je drahá, protože vyžaduje zpáteční cestu k serveru. Tato možnost také uloží výsledek této kontroly do mezipaměti.
Doufám, že to pomůže.