Die vorbereitete Anweisung ist eine etwas leistungsfähigere Version einer Anweisung und sollte immer mindestens so schnell und einfach zu handhaben sein wie eine Anweisung.
Die vorbereitete Anweisung kann parametrisiert werden
Die meisten relationalen Datenbanken verarbeiten eine JDBC / SQL-Abfrage in vier Schritten:
- Analysieren Sie die eingehende SQL-Abfrage
- Kompilieren Sie die SQL-Abfrage
- Planen / optimieren Sie den Datenerfassungspfad
- Führen Sie die optimierten Abfrage- / Erfassungs- und Rückgabedaten aus
Eine Anweisung führt für jede an die Datenbank gesendete SQL-Abfrage immer die vier oben genannten Schritte aus. Eine vorbereitete Anweisung führt die Schritte (1) - (3) im obigen Ausführungsprozess vor. Daher wird beim Erstellen einer vorbereiteten Anweisung sofort eine Voroptimierung durchgeführt. Der Effekt besteht darin, die Belastung des Datenbankmoduls zur Ausführungszeit zu verringern.
Meine Frage lautet nun: "Gibt es einen weiteren Vorteil der Verwendung von Prepared Statement?"
Antworten:
Vorteile eines
PreparedStatement
:Die Vorkompilierung und das DB-seitige Caching der SQL-Anweisung führt zu einer insgesamt schnelleren Ausführung und der Möglichkeit, dieselbe SQL-Anweisung in Stapeln wiederzuverwenden .
Automatische Verhinderung von SQL-Injection- Angriffen durch integriertes Entkommen von Anführungszeichen und anderen Sonderzeichen. Beachten Sie, dass Sie hierfür eine der
PreparedStatement
setXxx()
Methoden zum Festlegen der Werte verwenden müssenund somit nicht inline die Werte in der SQL - Zeichenfolge von String-Verkettungs.
Erleichtert Einstellung von Nicht-Standard - Java - Objekten in einer SQL - Zeichenfolge, zum Beispiel
Date
,Time
,Timestamp
,BigDecimal
,InputStream
(Blob
) undReader
(Clob
). Bei den meisten dieser Typen kann man nicht "einfach" machen,toString()
wie man es in einem einfachen tun würdeStatement
. Sie können sogar alles so umgestalten, dass esPreparedStatement#setObject()
innerhalb einer Schleife verwendet wird, wie in der folgenden Dienstprogrammmethode gezeigt:Welches kann wie folgt verwendet werden:
quelle
Statement
, aber es könnte einen Test wert sein.Sie sind (einmal) vorkompiliert und somit schneller für die wiederholte Ausführung von dynamischem SQL (wo sich Parameter ändern).
Das Zwischenspeichern von Datenbankanweisungen erhöht die Leistung der DB-Ausführung
Datenbanken speichern Caches von Ausführungsplänen für zuvor ausgeführte Anweisungen. Auf diese Weise kann das Datenbankmodul die Pläne für zuvor ausgeführte Anweisungen wiederverwenden. Da PreparedStatement Parameter verwendet, kann es bei jeder Ausführung als dieselbe SQL angezeigt werden. Die Datenbank kann den vorherigen Zugriffsplan wiederverwenden, wodurch die Verarbeitung reduziert wird. Anweisungen "inline" die Parameter in die SQL-Zeichenfolge und werden daher für die Datenbank nicht als dieselbe SQL angezeigt, wodurch die Cache-Nutzung verhindert wird.
Das binäre Kommunikationsprotokoll bedeutet weniger Bandbreite und schnellere Kommunikationsanrufe an den DB-Server
Vorbereitete Anweisungen werden normalerweise über ein Nicht-SQL-Binärprotokoll ausgeführt. Dies bedeutet, dass die Pakete weniger Daten enthalten, sodass die Kommunikation mit dem Server schneller ist. Als Faustregel gilt, dass Netzwerkoperationen um eine Größenordnung langsamer sind als Plattenoperationen, die um eine Größenordnung langsamer sind als CPU-Operationen im Speicher. Daher wirkt sich eine Verringerung der über das Netzwerk gesendeten Datenmenge positiv auf die Gesamtleistung aus.
Sie schützen vor SQL-Injection, indem sie Text für alle angegebenen Parameterwerte maskieren.
Sie bieten eine stärkere Trennung zwischen dem Abfragecode und den Parameterwerten (im Vergleich zu verketteten SQL-Zeichenfolgen), verbessern die Lesbarkeit und helfen Code-Betreuern, die Ein- und Ausgaben der Abfrage schnell zu verstehen.
Kann in Java getMetadata () und getParameterMetadata () aufrufen, um die Ergebnismengenfelder bzw. die Parameterfelder wiederzugeben
In Java werden Java-Objekte auf intelligente Weise als Parametertypen über setObject, setBoolean, setByte, setDate, setDouble, setDouble, setFloat, setInt, setLong, setShort, setTime und setTimestamp akzeptiert () Format).
Akzeptiert in Java SQL ARRAYs als Parametertyp über die setArray-Methode
Akzeptiert in Java CLOBs, BLOBs, OutputStreams und Readers als Parameter "Feeds" über die Methoden setClob / setNClob, setBlob, setBinaryStream, setCharacterStream / setAsciiStream / setNCharacterStream
Ermöglicht in Java das Festlegen von DB-spezifischen Werten für SQL DATALINK, SQL ROWID, SQL XML und NULL über die Methoden setURL, setRowId, setSQLXML und setNull
Erbt in Java alle Methoden von Statement. Es erbt die addBatch-Methode und ermöglicht zusätzlich das Hinzufügen einer Reihe von Parameterwerten, die mit der Menge der gestapelten SQL-Befehle über die addBatch-Methode übereinstimmen.
In Java ermöglicht eine spezielle Art von PreparedStatement (die Unterklasse CallableStatement) die Ausführung gespeicherter Prozeduren - Unterstützung für hohe Leistung, Kapselung, prozedurale Programmierung und SQL, DB-Verwaltung / Wartung / Optimierung der Logik und Verwendung proprietärer DB-Logik und -Funktionen
quelle
Connection.createStatement
undConnection.prepareStatement
. Dieses Design zwingt Sie dazu, gegen Schnittstellen zu arbeiten, damit Sie die spezifischen Implementierungsklassen nicht kennen und unnötige enge Kopplungen mit solchen Implementierungsklassen vermeiden müssen. Alle werden anhand von Beispielen in den Java-JDBC-Dokumenten und Java-Dokumenten erläutert. :)PreparedStatement
ist eine sehr gute Verteidigung (aber nicht narrensicher) bei der Verhinderung von SQL-Injection-Angriffen . Das Binden von Parameterwerten ist ein guter Weg, um zu verhindern, dass "kleine Bobby-Tische" einen unerwünschten Besuch machen.quelle
ORDER BY
) und / oder numerische Konstanten in bestimmten Orten (denkenLIMIT
,OFFSET
und anderer Paginierung Lösungen), so kann diese durch SQL - Injection angegriffen werden, auch wenn Prepared Statements und Parametrierung verwendet werden , wo immer möglich.Einige der Vorteile von PreparedStatement gegenüber Statement sind:
Weitere Informationen zum Problem der SQL-Injektion finden Sie unter http://www.journaldev.com/2489/jdbc-statement-vs-preparedstatement-sql-injection-example
quelle
nicht viel hinzuzufügen,
1 - Wenn Sie eine Abfrage in einer Schleife ausführen möchten (mehr als einmal), kann die vorbereitete Anweisung aufgrund der von Ihnen erwähnten Optimierung schneller sein.
2 - Parametrisierte Abfrage ist ein guter Weg, um SQL Injection zu vermeiden. Parametrisierte Abfragen sind nur in PreparedStatement verfügbar.
quelle
Die Anweisung ist statisch und die vorbereitete Anweisung ist dynamisch.
Die Anweisung ist für DDL geeignet und die Anweisung für DML vorbereitet.
Die Anweisung ist langsamer, während die vorbereitete Anweisung schneller ist.
mehr Unterschiede (archiviert)
quelle
CLOBs in einer Anweisung können nicht ausgeführt werden.
Und: (OraclePreparedStatement) ps
quelle
Wie von Mattjames zitiert
quelle
Die SQL-Injection wird von der vorbereiteten Anweisung ignoriert, sodass die Sicherheit der vorbereiteten Anweisung erhöht wird
quelle
quelle
Die Anweisung wird zum Ausführen statischer SQL-Anweisungen verwendet und kann keine Eingabeparameter akzeptieren.
PreparedStatement wird verwendet, um SQL-Anweisungen viele Male dynamisch auszuführen. Es werden Eingabeparameter akzeptiert.
quelle
Ein weiteres Merkmal der vorbereiteten oder parametrisierten Abfrage: Referenz aus diesem Artikel.
Diese Anweisung ist eine der Funktionen des Datenbanksystems, in dem dieselbe SQL-Anweisung wiederholt mit hoher Effizienz ausgeführt wird. Die vorbereiteten Anweisungen sind eine Art der Vorlage und werden von der Anwendung mit unterschiedlichen Parametern verwendet.
Die Anweisungsvorlage wird vorbereitet und an das Datenbanksystem gesendet, und das Datenbanksystem führt das Parsen, Kompilieren und Optimieren dieser Vorlage durch und speichert sie, ohne sie auszuführen.
Einige Parameter wie, bei denen die Klausel während der späteren Anwendung der Vorlagenerstellung nicht übergeben wird, senden diese Parameter an das Datenbanksystem, und das Datenbanksystem verwendet die Vorlage von SQL Statement und wird gemäß Anforderung ausgeführt.
Vorbereitete Anweisungen sind gegen SQL Injection sehr nützlich, da die Anwendung Parameter mit verschiedenen Techniken und Protokollen vorbereiten kann.
Wenn die Anzahl der Daten zunimmt und sich die Indizes zu diesem Zeitpunkt häufig ändern, schlagen vorbereitete Anweisungen möglicherweise fehl, da in dieser Situation ein neuer Abfrageplan erforderlich ist.
quelle
Statement
Schnittstelle führt statische SQL-Anweisungen ohne Parameter ausPreparedStatement
interface (erweiterte Anweisung) führt eine vorkompilierte SQL-Anweisung mit / ohne Parameter ausEffizient für wiederholte Ausführungen
Es ist vorkompiliert, damit es schneller ist
quelle
Keine Verwirrung: Denken Sie einfach daran
quelle
Ich habe alle Antworten auf diese Frage befolgt, um einen funktionierenden Legacy-Code mit -
Statement
(aber mit SQL Injections) in eine LösungPreparedStatement
mit einem viel langsameren Code zu ändern, da die Semantik umStatement.addBatch(String sql)
& schlecht verstanden wurdePreparedStatement.addBatch()
.Deshalb liste ich hier mein Szenario auf, damit andere nicht den gleichen Fehler machen.
Mein Szenario war
Im obigen Code hatte ich Tausende verschiedener Abfragen, die alle zur selben Anweisung hinzugefügt wurden, und dieser Code funktionierte schneller, da nicht zwischengespeicherte Anweisungen gut waren und dieser Code in der App selten ausgeführt wurde.
Um SQL Injections zu reparieren, habe ich diesen Code geändert in:
Sie sehen, ich habe angefangen, Tausende von
PreparedStatement
Objekten zu erstellen und konnte dann möglicherweise keine Stapelverarbeitung verwenden, weil mein Szenario dies erforderte - es gibt Tausende von UPDATE- oder INSERT-Abfragen und all diese Abfragen sind zufällig unterschiedlich.Das Reparieren der SQL-Injection war ohne Kosten für Leistungseinbußen obligatorisch, und ich glaube nicht, dass dies
PreparedStatement
in diesem Szenario möglich ist.Wenn Sie die integrierte Stapelverarbeitungsfunktion verwenden, müssen Sie sich nur darum kümmern, nur eine Anweisung zu schließen. Bei diesem List-Ansatz müssen Sie die Anweisung jedoch vor der Wiederverwendung schließen und eine vorbereitete Anweisung wiederverwenden
quelle