13 Datenbankanbindung mit JDBC
Inhalt
Einführung ·Structured Query Language ·Relationale Datenbanen
Literatur:
Die API zur Datenbankanbindung and SQL-Datenbanken gehört zu den
sogenannten Enterprise-Klassen, Material findet sich entsprechend
in [FFCM99] (Kapitel 2 und Kapitel 18,
eine SQL-Superkurzeinführung in Kapitel 8).
Ein fettes Buch zum Thema ist [WFC+99] (da zugehörige
online-Material
enthält auch ein kleines Tutorial.) Ein Datenbankbeispiel findet sich
auch in [Fla97a] (Kapitel 16)
Wir können hier nur sehr oberflächlich auf SQL eingehen, auf der
Webseite unseres Kurses sind ein paar weiterführende Informationen
aufgelistet.
-
JDBC: Teil der sogenannter
Enterprise-Klassen von Java78
- dient zum Arbeiten mit relationaler Datenbanken
- Java-Pakete: java.sql + Erweiterung javax.sql
- Interaktion mittels SQL-Anfragen79
- Unabhängig vom Datenbanksystem: Anpassung durch
entsprechende Treiber
- Grundschritte jeder Datenbankbenutzung (siehe Beispiel
auf Seite ?? (Vorraussetzung: Datenbank
läuft bereits)
-
Laden des Treibers
- Erzeugen einer Verbindung
- Erzeugen eines Datenbank- Befehls (Statement)
- Ausführen einer SQL-Anfrage
- Sammeln und Auswerten der Resultate
- Schließen der Resourcen
- Bei mehreren Befehlen: Schritte 3+4+5 müssen wiederholt werden
(nicht nur 4 und 5)
-
Kapselung/Abstraktion der Datenbankimplementierung
- Java-Objekt
- Benuztung: Registrierung beim Manager
- 4 Arten von Treibern
-
JDBC-ODBC-Bridge
- Native-API- Partly Java
- All Java
- Native protocol All-Java
- Sammlung von
Treibern
- bei uns Postgres-Datenbank mit
Typ-3-Treiber
-
Statement: zum Ausführen von
Datenbankbefehlen
- Interface java.sql.Statement
- erzeugt mittels createStatement() einer
Connection
Statement stmt = con.createStatement();
|
- eigentliches SQL-Statement in Java:
-
Code |
Anfrage |
Beispiel |
stmt.executeQuery(``SQL''); |
lesend |
SELECT |
stmt.executeUpdate(``SQL''); |
schreibend |
UPDATE, DELETE |
stmt.execute (``SQL'') |
stmt.getResultSet () |
|
versuchsweise |
- ein Statementobject = Ein Anfrage
- nach Gebrauch: schließen80
-
konzeptionell in einer Tabelle (Zeilen/Spalten)
aufgebaut entsprechend der gestellten Anfrage
- Objekt vom Interface ResultSet kapselt die Tabelle
- Zugriff:
-
Zeile
-
sequentiell Zeile für Zeile,
- Methode next() der Tabelle
- initial: vor der ersten Zeile
- nachgeordnet: Spalte
-
wahlfreier Zugriff
- (viele) Methoden, je nach Typ
- insbesondere getString(), getXXX() über Name
der Spalte (d.h. String-Argument) oder Index
(int-Argument von 1 bis n).
- allgemeinster Fall: getObject()
import java.sql.*;
public class JDBCSample {
public static void main(java.lang.String[] args) {
try {// This is where we load the driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch (ClassNotFoundException e) {
System.out.println("Unable to load Driver Class");
return;
}
try {// access is within a try/catch block.
Connection con =
DriverManager.getConnection("jdbc:odbc:companydb", "", "");
Statement stmt = con.createStatement(); // Create/execute statement
ResultSet rs = stmt.executeQuery("SELECT FIRST_NAME FROM EMPLOYEES");
while(rs.next()) { // Display the SQL results.
System.out.println(rs.getString("FIRST_NAME"));
}
rs.close(); stmt.close(); con.close(); // Freigeben der Rescourcen
}
catch (SQLException se) {
// Inform user of any SQL errors
System.out.println("SQL Exception: " + se.getMessage());
se.printStackTrace(System.out);
}
}
}
-
SQL-pakete importieren: import java.sql.*;
- postgres- Treiber einbinden:
try {
Class.forName("org.postgresql.Driver");
} catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
- Verbindung zur Datenbank `JavaUeb' herstellen:
String url = "jdbc:postgresql://sokrates/JavaUeb";
Connection con;
con = DriverManager.getConnection(url, "postgres", "");
- Nach getaner Arbeit die Verbindung schließen:
con.close();
SQL + relationale Datenbanken
|
Datentypen: JDBC ® Javatypen
|
JDBC Type |
Java |
ARRAY |
Array |
BIGINT |
long |
BINARY |
byte[] |
BIT |
boolean |
BLOB |
Blob |
CHAR |
String |
CLOB |
Clob |
DATE |
java.sql.Date |
DECIMAL |
java.math.BigDecimal |
DISTINCT |
mapping of underlying type |
DOUBLE |
double |
FLOAT |
double |
INTEGER |
int |
JAVA_OBJECT |
underlying Java-Class |
LONGVARBINARY |
byte[] |
LONGVARCHAR |
Strirg |
NULL |
? |
NUMERIC |
java.math.BigDecimal |
OTHER |
? |
REAL |
float |
REF |
Ref |
SMALLINT |
short |
STRUCT |
Struct |
TIME |
java.sql.Time |
TIMESTAMP |
java.sql.Timestamp |
TINYINT |
byte |
VARBINARY |
byte[] |
VARCHAR |
String |
Schemamanipulation: Erzeugen
|
-
Wichtigste Schemanmanipulation: Erzeugen einer
Tabelle: CREATE
- weitere: Verändern/Löschen (ALTER, DROP ...)
CREATE [ [ GLOBAL | LOCAL ] TEMPORARY]
TABLE <table_name>
( { <column_name> { <data_type> | <domain_name>}
[<column_size>]
[<column_constraint>] ...}
[DEFAULT <default_value], ..
[<table_constraint>], ...
[ ON COMMIT { DELETE | PRESERVE} ROWS ] )
-
Beispiel
CREATE TABLE COFFEES
(COF_NAME VARCHAR(32),
SUP_ID INTEGER,
PRICE FLOAT,
SALES INTEGER,
TOTAL INTEGER)
- Constraints: Standartbedingungen, per
Spalte oder per Tabelle
Spaltenconstraints (können
kombiniert werden) |
PRIMARY KEY |
Hauptspalte (für 0 oder 1 Spalte, keine doppelten Einträge) |
NOT NULL |
leerer Eintrag verboten |
UNIQUE |
Doppeleinträge verboten |
Tabellenconstraints |
UNIQUE |
keine Doppeleinträge, kann auch für
Teilmenge der Spalten definiert sein
(UNIQUE(<spalte_a>,...)) |
PRIMARY KEY |
Kombination mehrerer Spalten erlaubt! |
-
bei existierender Tabelle: Anfragen und Manipulation
einzelner Daten.
- im Wesentlichen:
-
Lesen: SELECT
- Erzeugen: INSERT
- Überschreiben: UPDATE
- von Einträgen pro Tabelle
-
Lesen mittel SELECT
- Komplexer SQL-Befehle, hier nur beipielhaft
-
SQL-code |
Erklärung |
SELECT * FROM BOOKS |
alle Spalten |
SELECT * FROM BOOKS ORDER BY
TITLE |
Sortieren |
SELECT TITLE,AUTHOR FROM BOOKS |
Teilmenge der Spalten |
SELECT * FROM BOOKS WHERE PRICE <
10.0 |
nach Prädikaten |
SELECT * FROM BOOKS WHERE PRICE <
10.0 OR EDITION = 1 |
log. Verknüpfung |
SELECT * FROM PERSONS WHERE TITLE
LIKE'%Java%' |
partieller Stringmatch |
SELECT * FROM BOOKS WHERE PRICE
IN (3.99, 4.99, 5.99) |
enthalten in expliz. Aufzählung |
SELECT * FROM BOOKS WHERE PRICE
IN SELECT PRICE FROM PRICES |
Schachtelung ( Subquery) |
- atomare Prädikate:82
=,<.>,<=,!=,<>, LIKE, IS NULL, IN, BETWEEN
- wichtig Stringmatch mit =, Unterscheidung
Groß/Kleinschreibung
- Matching von Teilen mit LIKE
-
_ höchstens ein Zeichen
- % beliebig viele Zeichen
Subqueries, Joins, Groups
|
-
Subqueries: geschachteltes
SELECT/IN.
- Join Anfragen an mehr als eine Tabelle
-
Restriktion des Outputs gemäß der Relation der
Tabellen
- zwei Arten:
-
equi-join/Innerer Join
-
symmetrisch
- gemeinsame Spalte in zwei Tabellen
- Dot-Syntax oder
JOIN- ON-Schlüsselwort
- Default-join = innerer Join
- äußerer Join
-
asymmetrisch
- zwei Arten: linker und rechter
äußerer Join (je nachdem, wo der Primärschlüssel
enthalten ist.
- LEFT JOIN/ RIGHT
JOIN
SQL-code |
Erkärung |
SELECT * FROM BOOKS WHERE PRICE
IN SELECT PRICE FROM PRICES |
Schachtelung in einer Tabelle |
SELECT * FROM CUSTOMERS, ORDERS WHERE
ORDERS.CUSTOMER_ID = CUSTOMERS.CUSTOMER_ID |
equi-join, Dot-Syntax |
SELECT * FROM CUSTOMERS INNER JOIN ORDERS
ON ORDERS.CUSTOMER_ID =
CUSTOMERS.CUSTOMER_ID |
equi-join,
JOIN-ON-Syntax |
SELECT * FRROM CUSTOMERS LEFT JOIN ORDERS
ON CUSTOMERS.CUSTOMER_ID =
ORDERS.CUSTOMER_ID |
Äußerer Join, Primärschlüssel in Tabelle
CUSTOMERS |
-
Ein paar nützliche Hilfs funktionen:
-
COUNT(*)
- Pro Spalte: AVG, SUM, MAX,
MIN
- CURRENT_DATE/CURRENT_TIMESTAMP: nützlich zum
Vergleich mit Datumseinträgen
- Stringconcatenation: ||
- Stringkonversion: UPPER,
LOWER
- TRIM: Abschneiden von Zeichen am
Anfang/ Ende einer Zeichenkette
- SUBSTRING: Teilzeichenkette
July 4, 2000