JDBC JDBC Contents Pierre Fierz Pierre Fierz Chapter 9 SQL in Programmiersprachen JDBC Java Database Connectivity JDBC Lecture Datenbanken 24.04.2014 Programmieren mit JDBC SQL-ROUTINEN und JDBC 1 SQL in Programmiersprachen 2 Java Database Connectivity JDBC Meta-Informationen SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen 3 Programmieren mit JDBC 4 SQL-ROUTINEN und JDBC 5 Meta-Informationen Pierre Fierz Berner Fachhochschule Technik und Informatik 9.1 Outline JDBC 9.2 SQL in Programmiersprachen Pierre Fierz 1 SQL in Programmiersprachen 2 Java Database Connectivity JDBC JDBC Pierre Fierz SQL in Programmiersprachen • Für grössere Applikationen ist es nötig SQL in einer Programmiersprache einzubetten. Java Database Connectivity JDBC • Diese Koppelung wird als Wirtssprachen-Koppelung Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen bezeichnet. • Dabei sind die folgenden Voraussetzungen nötig: • Die Schutzmechanismen der Datenbank müssen auch für 3 Programmieren mit JDBC SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen ein Programm gelten. • Fremdschlüsselbedingung, Assertion usw. müssen eingehalten werden. • Innerhalb der SQL-Befehle müssen Parameter (Variablen) 4 SQL-ROUTINEN und JDBC der Wirtssprache verwendet werden können. • Es muss klar definiert werden, wie die Datentypen der Datenbank in Datentypen der Wirtssprache übersetzt werden. 5 Meta-Informationen 9.3 9.4 SQL in Programmiersprachen (2) JDBC JDBC Outline Pierre Fierz Pierre Fierz SQL in Programmiersprachen • Es gibt mehere Möglichkeiten SQL in einer Programmiersprache einzubinden. • Wir werden hier die Java Datenbankanbindung JDBC anschauen. Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC SQL in Programmiersprachen 1 SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC 2 Java Database Connectivity JDBC SQL-ROUTINEN und JDBC Meta-Informationen Meta-Informationen 3 Programmieren mit JDBC • Eine weitere Möglichkeit ist embedded SQL, das für beliebige Sprachen standardisiert ist. • Ferner existieren auch objektrelationale Systeme wie Java 4 SQL-ROUTINEN und JDBC Persitence API (JPA). 5 Meta-Informationen 9.5 Was ist JDBC JDBC 9.6 JDBC JDBC Package-Struktur Pierre Fierz Pierre Fierz • JDBC besitzt die folgende Package-Struktur • JDBC = Java DataBase Connectivity ist mit ODBC (Open Database Connectivity) von Microsoft vergleichbar. • JDBC ist ein low-level oder call-level API um • • • • Die Verbindung zu einer Datenbank herzustellen SQL-Befehle abzusetzen Resultate zu analysieren und zu verarbeiten Information über die Datenbank bereitzustellen. SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL in Programmiersprachen JDBC Package Java Database Connectivity JDBC UserPackage <<implements>> <<uses>> java.sql VendorPackage SQL-ROUTINEN und JDBC Meta-Informationen Programmieren mit JDBC SQL-ROUTINEN und JDBC • java.sql: Dieses Package gehört ab Java 1.1 zum Meta-Informationen Standard API. • JDBC ermöglicht einen produktunabhängigen • VendorPackage: Dieses Package enthält für jedes Datenbankzugriff. Interface von java.sql eine entsprechende Implementationsklasse. • JDBC ist eine Basis für high-level API’s, die das Arbeiten mit SQL vollständig verstecken und z.B. direkt Java-Objekte verwalten. • Es stellt die eigentliche Funktionalität zur Verfügung und wird von Datenbank- oder Drittherstellern vertrieben. • UserPackage: Dieses Package erzeugt und benützt Variablen der verschiedenen Interfaces von java.sql. 9.7 9.8 JDBC Das Package java.sql Das Package java.sql (2) Pierre Fierz JDBC Pierre Fierz • Nachfolgend sind die wichtigsten Interfaces und Klassen des Packages java.sql dargestellt. SQL in Programmiersprachen Java Database Connectivity JDBC java.sql <<interface>> ResultSet <<interface>> <<creates>> Statement <<class>> <<interface>> DriverManager Driver <<creates>> • Damit der Java-Code unabhängig von der verwendeten Programmieren mit JDBC SQL-ROUTINEN und JDBC <<interface>> <<interface>> PreparedStatement <<interface>> <<interface>> Connection <<creates>> <<creates>> Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen werden niemals direkt mit new erzeugt. • Dazu existieren Get- oder Create-Methoden • Die Namen der Implementationsklassen bleiben dem Anwender Package verborgen. • Einzige Ausnahme ist der Name der Driverklasse. <<creates>> ResultSetMetaData Datenbank ist gelten für die Erzeugung von Objekten die folgenden Regeln: • Objekte von Implementationsklassen im VendorPackage Meta-Informationen <<creates>> SQL in Programmiersprachen DatabaseMetaData <<interface>> CallableStatement <<creates>> 9.9 Driver Interface JDBC Pierre Fierz • Die Aufgabe des Drivers ist, eine Verbindung zwischen dem Java-Programm und der Datenbank herzustellen. • Eine Driverimplementation muss eine “static section” enthalten, die die folgenden Aufgaben übernimmt: 1 2 Kreieren einer Instanz des Drivers Registrieren des Drivers beim Drivermanager SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen • Die gewünschten Drivers können mit der Methode Class.forname geladen werden (der Driver muss im Classpath sein). • Ab JDBC Version 4.0 muss der Driver nicht mehr explizit geladen werden 9.10 DriverManager Klasse • Diese Klasse enthält nur statische Methoden. • Für den Anwender ist die Methode getConnection, die die Verbindung mit der Datenbank aufnimmt am wichtigsten. • Der Methode muss eine sogennante JDBC URL übergeben werden. • An Hand dieser URL weiss der Drivermanager welche Datenbank geöffnet werden muss. • Die JDBC URL hat das folgende Format: jdbc:<subprotocol>:<subname> • <subprotocol> – ist der offizielle Name eines Drivers. Subprotokolle können von Driver Herstellern bei Javasoft registriert werden. • <subname> – dient dazu, die Datenbank zu identifizieren. Der genaue Aufbau dieses Teiles ist Herstellerabhängig. JDBC Pierre Fierz SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen Verbindung zu einer Datenbank aufnehmen • Die Klasse Drivermanager ist in der Lage den Driver zu finden und zu laden. Connection con = DriverManager.getConnection( "jdbc:mysql://db.bfh.ch/fierzdb" Name, Passwort) 9.11 9.12 Statement und Resultset Interface JDBC Metainformationen Pierre Fierz • Mit Hilfe eines Connection Objekts können Statement Objekte kreiert werden. • Statement dienen dazu, SQL-Befehle der Datenbank zu senden. • Die drei folgenden Methoden sind besonders wichtig: 1 2 3 executeQuery: für SELECT executeUpdate: für INSERT, UPDATE, DELETE, CREATE, DROP usw. execute: für SQL-Befehle, die mehr als ein Resultat liefern (stored Procedures); JDBC Pierre Fierz • Mit dem Interface DatabaseMetadata können SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen Informationen über das Datenbankschema geholt werden • • • • Tabellen Attribute Schlüssel usw. • Mit dem Interface ResultSetMetaData können Informationen über ein Objekt des Typs ResultSet gewonnen werden. SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen • Dies wird benutzt, wenn das Resultat eines Queries zur • Die Methode executeQuery gibt ein Objekt des Typs Kompilationszeit nicht bekannt ist. Resultset zurück. • Folgende Informationen sind verfügbar: • Anzahl Attribute • Name der Attribute • Tabelle der Attribute • Datentyp • usw. • Ein Resultset ist die Implementation einer Relation • Die Methode next iteriert durch alle Tupel der Relation hindurch. • Mit den Methoden get<Datatype> kann der Wert der einzelnen Attribute ermittelt werden. 9.13 Metainformationen (2) JDBC 9.14 Weitere Klassen Pierre Fierz JDBC Pierre Fierz • Die Klasse DriverPropertyInfo dient dazu, Informationen über einen bestimmten Driver zu erhalten. • Zum Beispiel kann man so erfahren, welche Parameter beim Öffnen der Datenbank (connect) notwendig sind (user, password usw.). • Es ist auch möglich bein Aufbau der Connection gewisse Einstellungen des Drivers zu verändern. • Bevor die Informationen zur Verfügung stehen, muss der SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen Driver geladen werden. SQL in Programmiersprachen • Neben den Klassen und Interfaces in der Abbildung existieren noch die folgenden Klassen im Package java.sql • Klassen für das Exceptionhandling • SQLException und Subklassen • SQLWarning • DataTruncation Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen • Date, Time, TimeStamp: Diese Klassen garantieren die Hohlen der Driver Properties Kompatibilität zwischen Datenbank und Java bezüglich Zeit und Datum. try { /* Laden des Drivers ab JDBC 4.0 nicht mehr noetig */ Class.forName("com.mysql.jdbc.Driver"); /* Driver hohlen */ Driver dv = DriverManager.getDriver("jdbc:mysql://a/b"); /* Hohlen der Driverproperties */ return dv.getPropertyInfo(url, po); } catch (SQLException e) { ; } • Types: Diese Klasse enthält Konstanten, welche die generischen SQL-Typen definieren 9.15 9.16 JDBC Outline JDBC Beispiele Pierre Fierz JDBC Pierre Fierz • Das nächste Beispiel zeigt der Aufbau der Verbindung zur Datenbank 1 SQL in Programmiersprachen 2 Java Database Connectivity JDBC SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC • Das JDBC Vendopackage muss im Classpath vorhanden sein. Verbindung zur Datenbank aufnehmen SQL-ROUTINEN und JDBC Meta-Informationen 3 Programmieren mit JDBC SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Connection con = null; Meta-Informationen // Verbindung mit der Datenbank aufnehmen. Mit Hilfe // des Subprotokolls "mysql" wird der // Drivermanager wissen, dass die Verbindung zu einer // Mysql-Datenbank aufgenommen werden muss. // // Bei Mysql ist die Angabe von User und Passwort // notwendig. try { con = DriverManager.getConnection( "jdbc:mysql://db.bfh.ch/fierzdb", user, passwd ); } catch (SQLException e) { // Verbindung kann nicht aufgenommen werden. System.exit(1); } 4 SQL-ROUTINEN und JDBC 5 Meta-Informationen 9.17 JDBC Beispiele (2) JDBC 9.18 JDBC Beispiele (3) Pierre Fierz JDBC Pierre Fierz • Das nächste Beispiel zeigt ein einfaches Select Beispiel. Absetzen eines Select Statements // Beispiel SELECT Befehl try { Statement stmt = con.createStatement(); // Aufbauen eines Queries ResultSet rs = stmt.executeQuery( "SELECT mNr, Name, Ort, Plz " + "FROM Mitarbeiter"); while (rs.next()) { System.out.print(rs.getInt(1) + " / " + rs.getString(2) + " / "); // Es ist auch möglich mit dem Namen des Feldes // auf die Daten zuzugreifen. System.out.println(rs.getString("Ort") + " " + rs.getString("Plz")); } // Statement explizit schliessen, damit die // Datenbankresourcen sofort freigegeben werden und // nicht erst bei einer Garbagecollection. stmt.close(); } catch (Exception e) { System.out.println(e); } SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC • Das nächste Beispiel zeigt einen Insert Befehl Ausführen eines Inserts // UPDATE Befehle try { Statement stmt = con.createStatement(); Meta-Informationen SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen // Absetzen eines Inserts. Dazu muss die Methode // executeUpdate verwendet werden. int changes = stmt.executeUpdate( "INSERT INTO Projekt (pNr, PName, aNr, Standort) " + "VALUES (101, ’Neues Projekt’, 3, ’Bern’)"); stmt.close(); } catch (Exception e) { System.out.println(e); } 9.19 9.20 JDBC Beispiele (4) JDBC JDBC Beispiele (5) Pierre Fierz JDBC Pierre Fierz • Prepared Statements dienen dazu, oft verwendete Befehle • Wenn der Benutzer die entsprechenden Rechte besitzt, können auch DDL Befehle ausgeführt werden. Kreieren einer Tabelle // Kreieren einer neuen Tabelle try { Statement stmt = con.createStatement(); SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen stmt.executeUpdate("CREATE TABLE kunde (" + "kNr INTEGER NOT NULL, " + "KName VARCHAR(30) NOT NULL, " + "Ort VARCHAR(30) NOT NULL," + "PRIMARY KEY (kNr))"); stmt.close(); } catch (Exception e) { System.out.println(e); } zu beschleunigen und gleichzeitig die Parameterübergabe zu vereinfachen Insert mit einem prepared Statement // Prepared Statements mit Parameteruebergabe. // erlaubt es ein SQL-Befehl mehrmals zu verwenden. try { PreparedStatement stmt = con.prepareStatement( "INSERT INTO Projekt " + "(pNr, PName, paNr, PStandort) VALUES (?,?,?,?)"); // Parameter uebergeben stmt.setInt(1, 25); stmt.setString(2, "Coop Baustelle"); stmt.setInt(3, 4); stmt.setString(4, "Belp"); // Befehl ausfuehren int changes = stmt.executeUpdate(); stmt.close(); } catch (Exception e) { System.out.println(e); } SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen 9.21 JDBC Beispiele (6) • Um herauszufinden ob ein Attribut einen Nullwert enthält, muss zuerst das entsprechende Attribut mit der Methode get<Datatyp> gelesen werden. • Anschliessend kann mit der Klassenmethode ResultSet.wasNull() gefragt werden, ob das Resultat ein Nullwert ist. Behandlung von NULL Werten // Behandlung von Nullvalues try { Statement stmt = con.createStatement(); JDBC 9.22 JDBC Beispiele (7) Pierre Fierz • In einem Resultset kann man auch Rückwärtsscrollen und JDBC Pierre Fierz den Cursor absolut oder relativ positionieren. SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen // Aufbauen eines Queries ResultSet rs = stmt.executeQuery( "SELECT mNr, Name, Vorgesetzter " + "FROM Mitarbeiter"); while (rs.next()) { int vorgesetzter = rs.getInt(3); if (rs.wasNull() == true) System.out.println("Mitarbeiter " + rs.getInt(1) + ". " + rs.getString(2) + " hat keinen Vorgesetzten"); } stmt.close(); } catch (Exception e) { System.out.println(e); } 9.23 Scrollen im Resultset // Beispiel Scroll im Resultset try { Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); // Aufbauen eines Queries ResultSet rs = stmt.executeQuery( "SELECT * FROM Mitarbeiter " + "ORDER BY mNr"); // Lieferanten in der Umgekehrten Reihenfolge Ausgeben rs.afterLast(); while (rs.previous()) { System.out.print(rs.getString("name")); } // Auf 7. Tupel positionieren if(rs.absolute(7)) { // Nun 5 Tupel rückwaerts rs.relative(-5); } stmt.close(); } catch (Exception e) { System.out.println(e); } SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen 9.24 JDBC Beispiele (8) JDBC JDBC Beispiele (9) • Im nächsten Beispiel wird ein neues Tupel in die Datenbank eingefügt. Pierre Fierz • Man kann Tupel in einem Resultset auch verändern und in der DB zurückspeichern. Update von Tupel im Resultset // Beispiel Update im Resultset try { Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen // Aufbauen eines Queries ResultSet rs = stmt.executeQuery( "SELECT * FROM Mitarbeiter " + "ORDER BY mNr"); // Setzen auf tupel sieben und Ort aendern if (rs.absolute(7)) { rs.updateString("Ort", "Genf"); rs.updateRow(); } stmt.close(); } catch (Exception e) { System.out.println(e); } Insert von Tupel im Resultset // Beispiel Update und Insert im Resultset try { Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); // Aufbauen eines Queries ResultSet rs = stmt.executeQuery("SELECT * FROM Projekt " + "ORDER BY pNr"); // Einfuegen eines Projektes rs.moveToInsertRow(); // Daten abfuellen rs.updateInt("pNr", 102); rs.updateString("PName", "Coop Baustelle"); rs.updateInt("paNr", 2); rs.updateString("Standort", "Belp"); // Lieferant zurueckschreiben rs.insertRow(); // Auf Urspruengliche Position zurueck rs.moveToCurrentRow(); stmt.close(); } catch (Exception e) { System.out.println(e); } JDBC Pierre Fierz SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen 9.25 Outline JDBC Aufruf von Prozeduren und Funktionen • Die Syntax für den Aufruf einer Prozedur hat die folgende Form: Pierre Fierz 1 SQL in Programmiersprachen 2 Java Database Connectivity JDBC 9.26 SQL in Programmiersprachen Java Database Connectivity JDBC SQL Syntax (JDBC call) <jdbc-call> ::= {CALL <procname> ([<arg> [, <arg>]. . . ])} <arg> ::= {? | <literal>} JDBC Pierre Fierz SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC SQL-ROUTINEN und JDBC Meta-Informationen 3 Programmieren mit JDBC Aufruf einer Prozedur mit ouput Parameter Meta-Informationen try { // Aufrufen der Prozedur "Stundenproc" CallableStatement cstmt = con.prepareCall( "{CALL Stundenproc(?, ?)}"); // Parameter nummer 1 setzen (Projektnummer) cstmt.setInt(1,2); // Rueckgabeparameter (Parameter 2) registrieren cstmt.registerOutParameter(2, Types.FLOAT); // Ausfuehren der Funktion cstmt.execute(); // Lesen und ausgeben des Resultats System.out.println(cstmt.getFloat(2)); } catch (Exception e) { System.out.println("*** " +e); } 4 SQL-ROUTINEN und JDBC 5 Meta-Informationen 9.27 9.28 Aufruf von Prozeduren und Funktionen (2) • Die Syntax für den Aufruf einer Funktion hat die folgende Form: SQL Syntax (JDBC call) <jdbc-funcall> ::= {? = CALL <procname> ([<arg> [, <arg>]. . . ])} <arg> ::= {? | <literal>} JDBC Prozeduren und Resultsets Pierre Fierz SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Aufruf einer Funktion JDBC Pierre Fierz • Prozeduren können auch Resultsets zurückgeben. • Dazu genügt es in der Prozedur ein normales Select Statement zu schreiben. Prozedur mit Resultset Meta-Informationen SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen CREATE PROCEDURE AnzProj() BEGIN SELECT a.aNr, a.AName, COUNT(*) FROM Abteilung a JOIN Projekt p ON a.aNr = p.paNr GROUP BY a.aNr, p.AName; END try { // Aufrufen der Funktion "Stundenfunc" CallableStatement cstmt = con.prepareCall( "{? = CALL Stundenfunc(?)}"); // Parameter nummer 2 setzen (ProjektNummer) cstmt.setInt(2,2); // Rueckgabewert (Parameter 1) registrieren cstmt.registerOutParameter(1, Types.FLOAT); // Ausfuehren der Funktion cstmt.execute(); // Lesen und ausgeben des Resultats System.out.println(cstmt.getInt(1)); } catch (Exception e) { System.out.println("*** " +e); } 9.29 Prozeduren und Resultsets (2) JDBC 9.30 Prozeduren und Resultsets (3) Pierre Fierz • In manchen DBMS (darunter auch Mysql) ist es möglich, • Die Prozedur kann nun in einem Programm aufgerufen werden. • Anschliessend kann der Resultset abgearbeitet werden. Aufruf einer Prozedur mit Resultset try { // Aufrufen der Funktion "AnzProj" CallableStatement cstmt = con.prepareCall("{call AnzProj()}"); // Ausfuehren der Funktion if (cstmt.execute()) { // ResultSet hohlen und lesen ResultSet rs = cstmt.getResultSet(); while (rs.next()) { System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getInt(3)); } } } catch (Exception e) { System.out.println("*** " +e); } JDBC Pierre Fierz dass eine Routine mehrere ResultSets zurückgibt. SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen • Die Anzahl Resultset ist gleich der Anzahl Select Statements in der Prozedur. Prozedur mit zwei Resultsets CREATE PROCEDURE AnzProj1() BEGIN -- Erstes ResultSet SELECT a.aNr, a.AName, COUNT(*) FROM Abteilung a JOIN Projekt p ON a.aNr = p.paNr GROUP BY a.aNr, p.AName; SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen -- Zweites ResultSet SELECT a.aNr, a.AName, 0 FROM Abteilung a WHERE NOT EXISTS (SELECT * FROM Projekt p WHERE a.aNr = p.paNr); END 9.31 9.32 Prozeduren und Resultsets (4) JDBC Outline Pierre Fierz JDBC Pierre Fierz • Das nächste Programmfragment ruft die Prozedur auf und listet anschliessend beide Resultate aus. Aufruf einer Prozedur mit mehreren Resultsets try { // Aufrufen der Funktion "AnzProj1" CallableStatement cstmt = con.prepareCall( "{call AnzProj1()}"); // Ausfuehren der Funktion if (cstmt.execute()) { do { // ResultSet hohlen und lesen ResultSet rs = cstmt.getResultSet(); while (rs.next()) { System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getInt(3)); } } while(cstmt.getMoreResults()); } } catch (Exception e) { System.out.println("*** " +e); } SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC 1 SQL in Programmiersprachen 2 Java Database Connectivity JDBC Meta-Informationen SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen 3 Programmieren mit JDBC 4 SQL-ROUTINEN und JDBC 5 Meta-Informationen 9.33 Metainformationen JDBC 9.34 ResultSetMetaData Pierre Fierz JDBC Pierre Fierz • Das nächste Beispiel zeigt, wie ein Resultset analysiert SQL in Programmiersprachen • Es gibt bei der Programmierung Probleme, die nicht mit den bisherigen Methoden gelöst werden können. • Insbesondere sind bei generischen Programmen die SQL Befehle zur Kompilationszeit nicht bekannt. Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen • Mit der Klasse ResultsetMetaData kann zur Laufzeit der Aufbau eines Resultsets bestimmt werden. • Mit der Klasse DatabaseMetaData können beliebige Informationen über das Datenbankschema gewonnen werden. 9.35 werden kann. Scrollen im Resultset // Beispiel fuer die Benutzung von ResultSetMetaData try { Statement stmt = con.createStatement(); // Aufbauen eines Queries ResultSet rs = stmt.executeQuery( "SELECT * FROM Mitarbeiter m natural join MitProj mp " + " natural join Projekt"); // Metadaten hohlen ResultSetMetaData rsm = rs.getMetaData(); // Anzahl Kolonnen bestimmen int cols = rsm.getColumnCount(); while (rs.next()) { // Name, Datentyp und Inhalt der einzelnen Kolonnen // abfragen und ausgeben for (int i = 1; i <= cols; i++) { String cna = rsm.getColumnName(i), cco = rs.getString(i); int cty = rsm.getColumnType(i); System.out.println(cna + " (" + cty + "): " + cco); } } stmt.close(); } catch (Exception e) { System.out.println(e); } SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen 9.36 DatabaseMetaData • Das nächste Beispiel zeigt, wie Informationen über die einzelnen Relationenschematas der Datenbank gewonnen werden kann. Scrollen im Resultset JDBC Die execute Methode Pierre Fierz SQL in Programmiersprachen Java Database Connectivity JDBC // Beispiel fuer die Benutzung von DatabaseMetaData try { DatabaseMetaData dbmd = con.getMetaData(); // Information ueber alle Tabellen String [] s = {"TABLE"}; ResultSet rs1 = dbmd.getTables("firma", null, "%", s); Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen SQL Befehl ein Query oder ein Update ist. • In diesem Fall wird man die execute Methode benutzen • Ist der Rückgabewert true, so war der Befehl ein Query Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen In diesem Fall kann mit der Methode getUpdateCount() die Anzahl veränderter Tupel ermittelt werden. JDBC Pierre Fierz • Im folgenden Beispiel kann ein beliebiges SQL Statement auf der Commando Zeile eingegeben werden. // Beispiel fuer die Benutzung von execute und // ResultSetMetaData try { Statement stmt = con.createStatement(); // SQL-Statement ist im 4. Argument der Kommandozeile: // Ausfuehren des Statements if (stmt.execute(args[3])) { // Das Statement ist ein Query wir muessen also // die Resultset und die Metadaten hohlen ResultSet rs = stmt.getResultSet(); ResultSetMetaData rsm = rs.getMetaData(); // Weitere Verarbeitung // ... } else { // Kein Query anzahl veraenderter Tuple herausgeben System.out.println("Update Count: " + stmt.getUpdateCount()); } stmt.close(); } catch (SQLException e) { System.out.println(e); } • Bei generischen Programmen weiss man oft nicht, ob ein • Ist der Rückgabewert false, so war der Befehl kein Query. 9.37 Scrollen im Resultset SQL in Programmiersprachen und der Resultset kann mit der Methode getResulSet() bestimmt werden. while (rs1.next()) { String tn = rs1.getString("TABLE_NAME"); // Einlesen aller Attribute der Tabelle ResultSet rs2 = dbmd.getColumns("firma", null, tn, null); while (rs2.next()) { // Ausgeben einiger Informationen System.out.println(rs2.getString("COLUMN_NAME") + " / " + rs2.getString("TYPE_NAME") + "(" + rs2.getInt("COLUMN_SIZE") + ")"); } } } catch (Exception e) { System.out.println(e); } Die execute Methode (2) JDBC Pierre Fierz SQL in Programmiersprachen Java Database Connectivity JDBC Programmieren mit JDBC SQL-ROUTINEN und JDBC Meta-Informationen 9.39 9.38