MySQL Connector/J besteht alle Tests der öffentlich zugänglichen JDBC Compliance Testsuite von Sun. Doch an vielen Stellen sagt die JDBC-Spezifikation nicht genau, wie eine Funktionalität implementiert werden soll.
In diesem Abschnitt wird für jede Schnittstelle untersucht, wie sich Ihre Implementierungsentscheidungen auf die Verwendung von MySQL Connector/J auswirken können.
Blob
Die BLOB-Implementierung erlaubt keine Modifikationen an Ort
und Stelle (sondern nur in Kopien, die von der Methode
DatabaseMetaData.locatorsUpdateCopies()
angezeigt werden). Daher sollten Sie Änderungen mit der
entsprechenden
PreparedStatement.setBlob()
- oder
ResultSet.updateBlob()
-Methode (für
aktualisierbare Ergebnismengen) in die Datenbank
zurückspeichern.
Seit Connector/J version 3.1.0 können Sie Blobs mit
Locators emulieren, indem Sie Ihrem JDBC-URL die Eigenschaft
'emulateLocators=true' hinzufügen. Sie müssen dann einen
Spaltenalias einsetzen, wobei der Wert der Spalte auf den
tatsächlichen Namen der Blob-Spalte in der
SELECT
-Anweisung gesetzt wird, die Sie
zum Abrufen des Blob schreiben. Die
SELECT
-Anweisung darf nur eine einzige
Tabelle referenzieren, die Tabelle muss einen
Primärschlüssel haben, und das SELECT
muss alle Spalten enthalten, die diesen Primärschlüssel
ausmachen. Der Treiber wird dann das Laden der
tatsächlichen Blob-Daten so lange aufschieben, bis Sie den
Blob abrufen und auf ihm entsprechende Abrufmethoden
aufrufen (getInputStream()
,
getBytes()
usw.).
CallableStatement
Seit Connector/J 3.1.1 werden über die Schnittstelle
CallableStatement
bei Verbindungen
mit MySQL 5.0 oder neuer gespeicherte Prozeduren
unterstützt. Die Methode
getParameterMetaData()
von
CallableStatement
wird gegenwärtig
noch nicht unterstützt.
Clob
Die CLOB-Implementierung erlaubt keine Modifikationen an Ort
und Stelle (sondern nur in Kopien, die von der Methode
DatabaseMetaData.locatorsUpdateCopies()
angezeigt werden). Daher sollten Sie Änderungen mit der
entsprechenden
PreparedStatement.setClob()
-Methode in
die Datenbank zurückspeichern. Die JDBC-API kennt keine
ResultSet.updateClob()
-Methode.
Connection
Im Gegensatz zu älteren Versionen von MM.MySQL wird die
Methode isClosed()
den Server nicht
pingen, um festzustellen, ob er noch lebendig ist.
Entsprechend der JDBC-Spezifikation gibt sie lediglich true
zurück, wenn closed()
auf der Verbindung
aufgerufen worden ist. Wenn Sie feststellen möchten, ob die
Verbindung noch steht, setzen Sie eine einfache Anfrage wie
beispielsweise SELECT 1
ab. Ist die
Verbindung ungültig geworden, löst der Treiber eine
Ausnahme aus.
DatabaseMetaData
Fremdschlüsselinformationen
(getImportedKeys()
/getExportedKeys()
und getCrossReference()
) sind nur für
InnoDB-Tabellen erhältlich. Da der Server diese
Informationen jedoch mit SHOW CREATE
TABLE
abruft, wird er auch andere Speicher-Engines
unterstützen, die Fremdschlüssel kennen.
PreparedStatement
PreparedStatements werden vom Treiber implementiert, da
MySQL keine vorbereiteten Anweisungen kennt. Dahler
implementiert der Treiber auch kein
getParameterMetaData()
oder
getMetaData()
, da er dann einen
kompletten SQL-Parser im Client benötigen würde.
Seit Version 3.1.0 verwendet MySQL Connector/J serverseitige vorbereitete Anweisungen und binär codierte Ergebnsmengen, wenn der Server diese ermöglicht.
Seien Sie vorsichtig, wenn Sie eine serverseitige
vorbereitete Anweisung mit
großen Parametern
verwenden, die mit setBinaryStream()
,
setAsciiStream()
,
setUnicodeStream()
,
setBlob()
oder
setClob()
eingestellt werden. Wenn Sie
die Anweisung erneut ausführen, aber dabei die großen auf
kleine Parameter umstellen möchten, müssen Sie
clearParameters()
aufrufen und alle
Parameter neu einstellen. Dies hat folgenden Grund:
Wenn der Parameter gesetzt ist, lässt der Treiber die großen Daten Band-extern in die vorbereitete Anweisung auf der Serverseite streamen (und zwar vor Ausführung der vorbereiteten Anweisung).
Wenn dies erledigt ist, wird der Stream, mit dem Daten auf der Clientseite gelesen wurden, geschlossen (genz JDBC-konform), und kann nicht mehr gelesen werden.
Wird der Parameter von groß auf klein umgestellt, muss
der Treiber den serverseitigen Zustand der vorbereiteten
Anweisung zurücksetzen, damit der neue Parameter den
Platz des vorherigen, großen Werts einnehmen kann.
Dadurch werden alle großen Daten, die bereits an den
Server geschickt wurden, entfernt, sodass sie mit einer
der Methoden setBinaryStream()
,
setAsciiStream()
,
setUnicodeStream()
,
setBlob()
oder
setClob()
erneut gesandt werden
müssen.
Um einen Parameter von einem großen auf einen kleinen Typ
umzustellen, müssen Sie folglich
clearParameters()
aufrufen und alle
Parameter der vorbereiteten Anweisung neu einstellen, ehe
diese wieder ausgeführt werden kann.
ResultSet
Nach Voreinstellung werden ResultSets vollständig abgeholt und in den Arbeitsspeicher geladen. Meist ist dies am effizientesten und durch den Entwurf des MySQL-Netzwerkprotokolls auch am einfachsten zu implementieren. Wenn Sie jedoch mit ResultSets arbeiten, die viele Zeilen oder große Werte enthalten, und in Ihrer JVM keinen Heap-Space für den erforderlichen Arbeitsspeicher zuweisen können, können Sie den Treiber auch veranlassen, die Ergebnisse zeilenweise hereinströmen zu lassen.
Um diese Funktionalität nutzen zu können, müssen Sie ein Statement-Objekt wie folgt erzeugen:
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE);
Die Kombination aus einer forward-only, nur-lesenden
Ergebnismenge der Größe
Integer.MIN_VALUE
ist für den Treiber
das Signal, die Ergebnismengen zeilenweise hereinströmen zu
lassen. Danach werden auch alle weiteren mit dieser
Anweisung abgerufenen Ergebnismengen zeilenweise eingelesen.
Dieser Ansatz hat einige Tücken. Sie müssen alle Zeilen der Ergebnismenge lesen (oder sie schließen), ehe Sie auf der Verbindung weitere Anfragen absetzen können. Sonst wird eine Ausnahme ausgelöst.
Die Sperren, die diese Anweisungen halten, können
frühestens freigegeben werden, wenn die Anweisung
abgeschlossen ist. (Dies gilt für
MyISAM
-Tabellensperren ebenso wie für
die Zeilensperren einiger anderer Speicher-Engines, wie etwa
InnoDB
.)
Wenn die Anweisung zu einer Transaktion gehört, werden die Sperren erst freigegeben, wenn die Transaktion fertig ist (was impliziert, dass auch die Anweisung zuerst fertig sein muss). Wie in den meisten anderen Datenbanken auch, sind Anweisungen erst dann abgeschlossen, wenn alle Ergebnisse gelesen wurden, oder die aktive Ergebnismenge der Anweisung geschlossen worden ist.
Daher sollten Sie Streaming-Ergebnisse immer so schnell wie möglich lesen, wenn die von der Anweisung referenzierten Tabellen weiterhin nebenläufig zugänglich sein sollen.
ResultSetMetaData
Die Methode isAutoIncrement()
funktioniert nur mit MySQL 4.0 und neuer.
Statement
Wenn Sie ältere JDBC-Treiberversionen als 3.2.1 in Verbindung mit älteren älteren Server-Versionen als 5.0.3 benutzen, hat die Methode "setFetchSize()" keine andere Wirkung, als das Ergebnismengen-Streaming umzuschalten, wie oben beschrieben.
MySQL unterstützt keine SQL-Cursors und der JDBC-Treiber emuliert sie auch nicht. Daher hat "setCursorName()" keine Wirkung.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.