Ten eerste is het belangrijk om onderscheid te maken tussen door de client en de server voorbereide verklaringen.
Door de klant opgestelde verklaringen
Door de klant opgestelde verklaringen zijn "geëmuleerde" voorbereide verklaringen. Dit betekent dat de tekenreeks van de SQL-instructie aan de clientzijde wordt getokeniseerd en dat eventuele tijdelijke aanduidingen worden vervangen door letterlijke waarden voordat de instructie naar de server wordt verzonden voor uitvoering. Bij elke uitvoering wordt een compleet SQL-statement naar de server gestuurd. U kunt het algemene logboek gebruiken om te onderzoeken hoe dit werkt. bijv.
de volgende code:
ps=conn.prepareStatement("select ?")
ps.setInt(1, 42)
ps.executeQuery()
ps.setInt(1, 43)
ps.executeQuery()
zou in het logboek verschijnen:
255 Query select 42
255 Query select 43
De "query" geeft aan dat, op protocolniveau, een COM_QUERY
commando wordt verzonden met de volgende instructiereeks.
Op de server voorbereide verklaringen
Door de server voorbereide instructies zijn "echte" voorbereide instructies, wat betekent dat de vraagtekst naar de server wordt verzonden, geparseerd en tijdelijke aanduiding- en resultaatinformatie wordt teruggestuurd naar de client. Dit krijg je als je useServerPrepStmts=true
instelt . De instructiereeks wordt slechts één keer naar de server verzonden met een COM_STMT_PREPARE
bel (gedocumenteerde hier
). Elke uitvoering wordt uitgevoerd door het verzenden van een COM_STMT_EXECUTE
met de voorbereide instructiehandle en de letterlijke waarden om de tijdelijke aanduidingen te vervangen.
In tegenstelling tot het door de klant voorbereide voorbeeld, kunnen we een soortgelijk codeblok gebruiken (maar deze keer met door de server voorbereide instructies ingeschakeld):
ps2=conn2.prepareStatement("select ?")
ps2.setInt(1, 42)
ps2.executeQuery()
ps2.setInt(1, 43)
ps2.executeQuery()
En het logboek zou laten zien:
254 Prepare select ?
254 Execute select 42
254 Execute select 43
U kunt zien dat de instructie is voorbereid voordat deze wordt uitgevoerd. Het logboek doet ons een plezier en toont de volledige verklaring voor de uitvoering, maar in feite worden alleen de tijdelijke waarden voor elke uitvoering van de client naar de server verzonden.
Voorbereide verklaringen in cache opslaan
Veel verbindingspools slaan voorbereide instructies op in de cache voor gebruik van een verbinding, wat betekent dat als u conn.prepareStatement("select ?")
aanroept , retourneert het dezelfde PreparedStatement
instantie op opeenvolgende aanroepen met dezelfde instructiereeks. Dit is handig om te voorkomen dat dezelfde string herhaaldelijk op de server wordt voorbereid wanneer verbindingen tussen transacties worden teruggestuurd naar de pool.
De MySQL JDBC-optie cachePrepStmts
zal op deze manier voorbereide verklaringen in de cache opslaan (zowel door de client als de server voorbereide verklaringen) en de "bereidbaarheid" van een verklaring in de cache opslaan. Er zijn enkele instructies in MySQL die niet aan de serverzijde kunnen worden voorbereid. De chauffeur zal proberen een verklaring op de server voor te bereiden als hij denkt dat dit mogelijk is en, als de voorbereiding mislukt, terugvallen op een door de klant opgestelde verklaring. Deze controle is duur omdat er een retourtje naar de server nodig is. De optie slaat ook het resultaat van deze controle op in de cache.
Ik hoop dat dit helpt.