Arten von Aussagen

Wir haben bereits die einfachste Statement- Schnittstelle gesehen . Und obwohl es für die Arbeit durchaus geeignet ist, ist es für komplexe Abfragen nicht so gut geeignet. In einigen Quellen wird die Meinung geäußert, dass die Verwendung von Statement überhaupt nicht erforderlich ist – stattdessen eignen sich komplexere und funktionsreichere Schnittstellen.

  • PreparedStatement
  • CallableStatement

Es stellt sich eine durchaus berechtigte Frage: Warum werden diese Schnittstellen benötigt? Lass es uns herausfinden.

Zunächst werfen wir einen Blick auf die PreparedStatement- Schnittstelle und andere JDBC-Funktionen. Wir werden uns später der CallableStatement- Schnittstelle zuwenden – ihre Verwendung ist erstens nicht so häufig und zweitens kann die Konversation nach all den Überlegungen bereits recht kurz gehalten werden.

Außerdem ist PreparedStatement eine große Hilfe bei dem beliebten Ansatz zum Datenbank-Hacking namens SQL Injection.

Aber dazu etwas später mehr.

PreparedStatement

Wenn Sie versuchen, den Namen PreparedStatement zu übersetzen , erhalten Sie so etwas wie „vorbereitete Anweisung“. Das wichtigste Wort hier ist „vorbereitet“. Was ist „Bereitschaft“?

Bevor wir uns mit diesem Thema befassen, schlage ich vor, einen aus Bequemlichkeitsgründen recht wichtigen Punkt zu betrachten, der sehr häufig vorkommt. Daher müssen wir in manchen Anwendungen Kontaktdaten in die Tabelle CONTACT einfügen. Dazu müssen wir eine Abfrage wie diese vorbereiten:

INSERT INTO JC_CONTACT (FIRST_NAME, LAST_NAME, PHONE, EMAIL) VALUES (‘Harry’,'Potter','+79112345678','harry@example.com);

Auf den ersten Blick scheint alles nicht so schwierig und beängstigend zu sein. Wir müssen einen Code schreiben, der die benötigte Zeichenfolge aus den Parametern sammelt: Vorname, Nachname, Adresse und Telefonnummer. Sie müssen nur bedenken, dass alle Zeichenfolgendaten von einem einfachen Anführungszeichen umgeben sein müssen.

Wenn wir dies in einer separaten Funktion tun, erhalten wir etwa Folgendes:

public String buildInsert(String firstName,, String lastName, String phone, String email) {
    String sql = "INSERT INTO JC_CONTACT (FIRST_NAME, LAST_NAME, PHONE, EMAIL)+
             	”VALUES ('" + firstName + "','" + lastName + "','" + phone + "','" + email + ")";
    return sql;
}

Wir übergeben den Vornamen, den Nachnamen, die Telefonnummer und die Adresse an die Parameterfunktion im Formular und erstellen daraus eine SQL-Abfragezeichenfolge. Zitate verderben das Bild ein wenig, aber bisher ist es nicht gruselig.

Ok, was ist mit den Zahlen? Sie müssen nicht in Anführungszeichen gesetzt werden. Opanki, im einen Fall braucht man Zitate, im anderen nicht. Die Situation wird immer komplizierter.

Fügen wir nun ein weiteres Problem hinzu: Was ist, wenn sich in der Zeichenfolge ein gewöhnliches Anführungszeichen (und nicht einmal eines) befindet? Solche Angebote müssen Sie zunächst suchen und bearbeiten. Mdaaa. Irgendwie beginnen wir uns unwohl zu fühlen.

Wenn wir jetzt die Datumsverarbeitung hinzufügen, wird die Aufgabe völlig langweilig – Sie müssen eine Menge Arbeit leisten. Datumsangaben sind im Allgemeinen unangenehm – verschiedene SQL-Server akzeptieren unterschiedliche Formate für Datumsangaben.

Was sehen wir also? Wenn wir Parameter innerhalb der Abfrage verwenden müssen, wird das manuelle Erstellen der Abfrage sehr unangenehm. Und nicht nur unangenehm – ich würde sogar sagen langweilig. Es gibt eine große Anzahl von Fällen, die es zu berücksichtigen gilt, und das ist eine furchtbar langweilige Aufgabe. Grundsätzlich wurde für solche Fälle die Schnittstelle PreparedStatement vorgeschlagen .

Mit dieser Anfrage können Sie zwei Dinge tun:

  • Bereiten Sie im Voraus eine Anfrage vor, in der Sie angeben, an welchen Stellen die Parameter ersetzt werden sollen
  • Legen Sie Parameter eines bestimmten Typs fest und führen Sie dann eine Abfrage mit bereits festgelegten Parametern aus

PreparedStatement-Beispiel

Die Struktur für PreparedStatement für unsere Option zum Festlegen von Parametern sieht folgendermaßen aus:

// Example variables
String firstName = "Harry";
String lastName = "Potter";
String phone = "+12871112233";
String email = "harry@example.com";

// Request with indication of places for parameters in the form of "?"
String sql = "INSERT INTO JC_CONTACT (FIRST_NAME, LAST_NAME, PHONE, EMAIL) VALUES (?, ?, ?, ?)";

// Create a request. The con variable is an object of type Connection
PreparedStatement stmt = con.prepareStatement(sql);

// Set parameters
stmt.setString(1, firstName);
stmt.setString(2, lastName);
stmt.setString(3, phone);
stmt.setString(4, email);

// Execute the request
stmt.executeUpdate();

Wie Sie sehen, ist alles ganz einfach.

Beim Schreiben einer SQL-Abfrage werden zunächst die Stellen, an denen Parameter ersetzt werden müssen, mit Fragezeichen geschrieben – „?“.

Zweitens wird die Anfrage durch den Aufruf von con.prepareStatement() erstellt .

Drittens erfolgt die Einstellung der Parameter über die Angabe von Anzahl und Wert. Bitte beachten Sie, dass die Anzahl der Parameter bei 1 beginnt und nicht bei 0, wie wir es bei der Arbeit mit Arrays und Sammlungen gewohnt sind.

Die PreparedStatement- Schnittstelle enthält Methoden zum Festlegen von Zeichenfolgen – setString() , zum Festlegen von Zahlen – setInt() , setLong() , setDouble() , zum Festlegen von Datumsangaben – setDate() . Und komplexere Typen – das ist in der Dokumentation zu sehen.

Viertens wird der Aufruf von stmt.executeUpdate() bereits ohne Angabe der Abfragezeichenfolge ausgeführt.

Ich empfehle dringend, sich mit PreparedStatement anzufreunden – dies ist ein sehr effektives Tool.