Mit JDBC (Java Database Connectivity) wird eine API der Java-Plattform bezeichnet, die u.a. eine Schnittstelle zu relationalen Datenbanken bereitstellt. Mit JDBC können Verbindungen zu Datenbanken hergestellt werden und Anweisungen mit Hilfe der Datenbanksprache SQL (Structured Query Language) an die Datenbank gerichtet werden. SQL ist eine für relationale Datenbanken weit verbreitete Sprache, die zum großen Teil standardisiert ist. Ein wichtiger Begriff im Zusammenhang mit relationalen Datenbanken ist Tabelle. Eine Tabelle ist ein Satz von Datenelementen (Zellen), die in vertikalen Spalten und horizontalen Zeilen angeordnet sind. Dabei ist die Anzahl der Spalten festgelegt und die Anzahl der Zeilen ist theoretisch nicht beschränkt. Die folgende Darstellung zeigt eine Tabelle mit m Spalten und n Zeilen; die Datenelemente sind mit x bezeichnet. S1 S2 ... Sm --------------------------- x11 x12 ... x1m x21 x22 ... x2m . xn1 xn2 ... xnm Die SQL-Anweisungen CREATE TABLE MyTable (name VARCHAR(30), khm SMALLINT) INSERT INTO MyTable VALUES ('Hans im Glueck', 83) könnten zur folgenden Tabellendarstellung führen: name khm --------------------------- 'Hans im Glueck' 83 Wichtige JDBC-Klassen sind im Paket Versionen (JDK 6): Die freie Datenbank Apache Derby wurde in JDK 6 mit dem Namen "Java DB" aufgenommen. Derby basiert urspünglich auf der Java-Datenbank Cloudscape, wobei Cloudscape von IBM im Oktober 2004 an die Apache Software Foundation übergeben wurde (Java DB alias Derby alias Cloudscape). Die statische Methode Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); Es stehen folgende Methoden beim Arbeiten mit Datenbanktreibern zur Verfügung: java.sql Class DriverManager Methode: static void registerDriver(Driver driver) static void deregisterDriver(Driver driver) static Enumeration<Driver> getDrivers() static Driver getDriver(String url) Die erste Methode registriert den Datenbanktreiber. Eine neu geladene
Treiberklasse sollte die Methode public class NameOfDriver implements java.sql.Driver { static { try { java.sql.DriverManager.registerDriver(new NameOfDriver()); } catch (SQLException e) { System.out.println(e.toString()); } } ... } Das Registrieren des Treibers beim Treibermanager erfolgt daher automatisch
beim Laden der Treiberklasse mittels Driver d = DriverManager.getDriver("jdbc:derby:"); System.out.println(d.getClass().getName()); Nachdem ein bestimmter JDBC-Treiber für eine dazugehöriges DBMS geladen wurde, kann eine Verbindung zu einer Datenbank hergestellt werden. Zu diesem Zweck werden folgende Methoden bereitgestellt: java.sql Class DriverManager Methode: static Connection getConnection(String url) static Connection getConnection(String url, Properties info) static Connection getConnection(String url, String user, String password) Bei allen drei Methoden ist eine Datenbank-URL erforderlich. Diese URL
beginnt mit jdbc:derby:databaseName;URLAttributes Es kann das optionale URL-Attribut Properties info = new Properties(); info.put("create", "true"); info.put("user", "user1"); info.put("password", "password1"); Connection con = DriverManager.getConnection("jdbc:derby:derbyDB", info); Um SQL-Anweisungen von einem DBMS ausführen zu lassen, wird zunächst ein
java.sql Interface Connection Methode: Statement createStatement() Nachdem ein Ausführungsobjekt von einer Datenbankverbindung erzeugt wurde, stehen folgende Methoden zur Verfügung: java.sql Interface Statement Methode: int executeUpdate(String sql) ResultSet executeQuery(String sql) Die Methode CREATE TABLE MyTable ( name VARCHAR(30), khm SMALLINT ) Dabei hat die Tabelle den Namen Statement stmt = con.createStatement(); stmt.executeUpdate("CREATE TABLE MyTable (" + "name VARCHAR(50), " + "khm INTEGER" + ")"); Als nächstes soll in die neu angelegte Tabelle ein Eintrag vorgenommen
werden, indem ebenfalls die Methode stmt.executeUpdate("INSERT INTO MyTable VALUES (" + "'Hans im Glueck', " + "83" + ")"); Die Datenbankanweisung fügt eine neue Zeile von Daten ein, mit dem Eintrag
Mit der Methode java.sql Interface ResultSet Methode: String getString(int columnIndex) String getString(String columnName) int getInt(int columnIndex) int getInt(String columnName) boolean next() Einzelne Werte können abgerufen werden, indem entweder die Spaltennummer
oder der Spaltenname angegeben wird. Die Nummerierung der Tabellenspalten beginnt
mit dem Wert 1. Beim Aufruf von "Getter-Methoden" versucht der JDBC-Treiber
SQL-Datentypen (wie z.B. ResultSet rs = stmt.executeQuery("SELECT * FROM MyTable"); rs.next(); System.out.print(rs.getString(1) + ", "); System.out.println(rs.getInt(2)); Das Falls eine Tabelle innerhalb einer Datenbank nicht mehr benötigt wird kann
die SQL-Anweisung stmt.executeUpdate("DROP TABLE MyTable"); Viele in diesem Abschnitt vorgestellte Methoden von Klassen im Paket
java.sql Class SQLException Methode: int getErrorCode() String getSQLState() SQLException getNextException() Die Methode try { ... // Mehodenaufrufe die eine SQLException ausloesen ... } catch (SQLException e) { while (e != null) { System.out.println(e.toString()); System.out.println("ErrorCode: " + e.getErrorCode()); System.out.println("SQLState: " + e.getSQLState()); e = e.getNextException(); } } Liegt z.B. ein syntaktischer Fehler innerhalb der SQL-Anweisung vor erscheint folgende Fehlermeldung (bei Syntaxfehlern beginnt die SQL-Statusnummer mit einer 42): SQL Exception: Syntax error: ... ErrorCode: 30000 SQLState: 42X01 SQL-Satusnummern werden zu Blöcken zusammnengefasst, die mit denselben Zahlen bzw. Buchstaben beginnen. Statusnummern, die mit ein X beginnen sind speziell für das DBMS Derby. Einige SQLState-Blöcke sind: 04... Datenbank-Authentifikations-Fehler (z.B. 04501 Database connection refused) 08... Verbindungsfehler (z.B. 08001 No suitable driver) 22... Datenfehler (z.B. 22003 The resulting value is outside the range for the data type <datatypeName>) 42... Syntaxfehler (z.B. 42X01 Syntax error: <error>) X0X.. Ausfühungsfehler (z.B. X0X05 Table '<tableName>' does not exist) XCY.. Property-Fehler (z.B. XCY03 Required property '<propertyName>' has not been set) ..... Neben SQL-Ausnahmen können auch SQL-Warnungen erzeugt werden. Warnungen
können von java.sql Interface Connection Methode: SQLWarning getWarnings() Der Aufruf der Methode java.sql Class SQLWarning Methode: SQLWarning getNextWarning() SQL-Warnungen können in ähnlicher Weise wie SQL-Ausnahmen behandelt werden: Connection con = DriverManager.getConnection("jdbc:derby:derbyDB;create=true"); SQLWarning w = con.getWarnings(); while (w != null) { System.out.println(w.toString()); System.out.println("ErrorCode: " + w.getErrorCode()); System.out.println("SQLState: " + w.getSQLState()); w = w.getNextWarning(); } Durch Angabe des URL-Attributs SQL Warning: Database 'derbyDB' not created, connection made to existing database instead. ErrorCode: 10000 SQLState: 01J01 Das folgende kurze Listing erzeugt zunächst eine Derby-Datenbank und stellt
eine Verbindung zu dieser her. Anschließend wird eine Tabelle mit zwei Spalten
angelegt und ein Eintrag vorgenommen. Der Eintrag wird danach mit einer SQL-Anweisung
wieder ausgelesen und in der Konsole ausgegeben. Schließlich wird die verwendete
Tabelle wieder gelöscht. Beim Erstellen einer neuen Derby-Datenbank wird im
aktuellen Verzeichnis ein neuer Ordner mit dem Namen der Datenbank erstellt, in
dem sich weitere Verzeichnisse und Dateien befinden. Ein Verzeichnis lautet z.B.
java -classpath .;c:/db-derby/lib/derby.jar JDBCExample Listing 6.1. /* * JDBCExample.java * */ import java.sql.*; public class JDBCExample { public static void main(String[] args) { try { Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); } catch (ClassNotFoundException e) { System.out.println(e.toString()); System.exit(1); } try { Connection con = DriverManager.getConnection("jdbc:derby:derbyDB;create=true"); Statement stmt = con.createStatement(); String strCreateMyTable = "CREATE TABLE MyTable (" + "name VARCHAR(50), " + "khm INTEGER" + ")"; stmt.executeUpdate(strCreateMyTable); String strInsertIntoMyTable = "INSERT INTO MyTable VALUES (" + "'Hans im Glueck', " + "83" + ")"; stmt.executeUpdate(strInsertIntoMyTable); ResultSet rs = stmt.executeQuery("SELECT * FROM MyTable"); rs.next(); System.out.print(rs.getString(1) + ", "); System.out.println(rs.getInt(2)); stmt.executeUpdate("DROP TABLE MyTable"); rs.close(); stmt.close(); con.close(); } catch (SQLException e) { while (e != null) { System.out.println(e.toString()); System.out.println("ErrorCode: " + e.getErrorCode()); System.out.println("SQLState: " + e.getSQLState()); e = e.getNextException(); } } } } |
|