10_DatenhaltungDatenbanken_06092011

Werbung
Vorlesung Informatik II
Universität Augsburg
Wintersemester 2011/2012
Prof. Dr. Bernhard Bauer
Folien von: Prof. Dr. Robert Lorenz
Lehrprofessur für Informatik
10. Java: Datenhaltung mit Datenbanken
1
Datenbank-Programme
Derby (Hersteller: Apache Foundation)
Für die lokale Installation auf ihrem Rechner
Download von Datenbank und Treiber (jar-Datei):
http://db.apache.org/derby/
 Datei entpacken und Pfad merken
 Pfad im Classpath eintragen:
java –Xbootclasspath/a: <Pfad der jar-Datei>
Beim ersten Programmstart muss man Tabellen erzeugen
(create-Anweisung)‫‏‬
Bei erneutem Start stehen diese Tabellen zur Verfügung.
2
Datenbank-Programme
MySQL
Haben wir auf unserem Server installiert
(aiomr.informatik.uni-augsburg.de):
Nur erreichbar über Uni-Netz oder VPN-Verbindung
Download des Treibers (jar-Datei):
http://www.mysql.com/products/connector/j/
 Datei entpacken und Pfad merken
 Als externe jar-Datei in Eclipse-Projekt eintragen
Tabellen zum Abfragen sind angelegt
(keine neuen Tabellen anlegen!)
3
ODBC - Schnittstelle
Open Database Connectivity (ODBC)
Für alle kommerziellen und freien DBMS gibt es die
einheitliche, standardisierte Benutzerschnittstelle ODBC
ODBC verwendet SQL
Der ODBC-Treiber eines DBMS bietet eine ProgrammierSchnittstelle (API) für C-Programme
Über ODBC kann eine Anwendung eine Datenbank unabhängig
von ihrer Implementierung über SQL-Befehle verwaltet werden
4
JDBC - Schnittstelle
Java Database Connectivity (JDBC)
Für den Zugriff über Java-Programme existiert die entsprechende
Schnittstelle JDBC
Das Paket java.sql stellt Klassen für den Zugriff auf
Datenbanken über ihre JDBC-Schnittstelle bereit
Über diese Schnittstelle können wir einheitlich sowohl
auf die Derby-, als auch auf die MySQL-Datenbank zugreifen!
5
Das Paket java.sql
Schritt 1: Laden einer JDBC-Treiber-Klasse (DB-spezifisch)
Klassenoperation der Klasse Class:
static Class forName(String className)
A call to forName("X") causes the class named X to be initialized
Returns: Class object for the class with the specified name.
className fully qualified name of the desired class.
Class
Metaklasse zur Verwaltung von Datentypen
6
Das Paket java.sql
Schritt 1: Laden einer JDBC-Treiber-Klasse (DB-spezifisch)
Class.forName(
“org.apache.derby.jdbc.EmbeddedDriver”);
Class.forName(“com.mysql.jdbc.Driver”);
7
Das Paket java.sql
Schritt 2: Verbindung zur DB herstellen (DB-spezifisch)
Klassenoperation der Klasse DriverManager
static Connection getConnection(String url,
String User, String password)
Attempts to establish a connection to the given database URL.
Attempts to select a driver from the set of registered JDBC drivers.
url
DriverManager
a database url of the form
jdbc:subprotocol:subname
Verwaltet geladene Treiber-Klassen
8
Das Paket java.sql
Schritt 2: Verbindung zur DB herstellen (DB-spezifisch)
Connection c = DriverManager.getConnection(
“jdbc:derby:derbyDB;create=true”,””,””);
Connection c = DriverManager.getConnection(
“jdbc:mysql://aiomr.informatik.uni-augsburg.de:
3306/theDatabase”,”user”,”password”);
9
Das Paket java.sql
Schritt 3: Anweisungs-Objekt für SQL-Anfragen (einheitlich!)
Operation der Schnittstelle Connection
Statement createStatement()
Creates a Statement object for sending SQL statements to the
database.
Connection A connection (session) with a specific database.
SQL statements are executed within the context
10
Das Paket java.sql
Schritt 3: Anweisungs-Objekt für SQL-Anfragen (einheitlich!)
Statement abfrage = c.createStatement();
11
Das Paket java.sql
Schritt 4: SQL-Anweisung ausführen (einheitlich!)
Operationen der Schnittstelle Statement
ResultSet executeQuery(String query)
executes the given SQL statement, returns a single ResultSet
object.
ResultSet
contains the data produced by the given query;
never null
Statement
The object used for executing a static SQL
statement and returning the results it produces.
12
Das Paket java.sql
Schritt 4: SQL-Anweisung ausführen (einheitlich!)
Operationen der Schnittstelle Statement
boolean execute(String sql)
executes the given SQL statement, which may return multiple
results.
use getResultSet,getMoreResults to get the result(s).
13
Das Paket java.sql
Schritt 4: SQL-Anweisung ausführen (einheitlich!)
Operationen der Schnittstelle Statement
int executeUpdate(String sql)
executes INSERT, UPDATE, or DELETE statements
Returns: the row count for statement
14
Das Paket java.sql
Schritt 4: SQL-Anweisung ausführen (einheitlich!)
Operationen der Schnittstelle Statement
ResultSet getResultset()
Returns data from previous execute
15
Das Paket java.sql
Schritt 4: SQL-Anweisung ausführen (einheitlich!)
Operationen der Schnittstelle Statement
void close()
Releases database and JDBC resources
16
Das Paket java.sql
Tabelle kreieren:
String befehl =
“CREATE TABLE ‘Vorlesung’ (
‘ID’ INTEGER NOT NULL,
‘Name’ VARCHAR(20) NOT NULL,
‘Jahr’ CHAR(4) NOT NULL,
‘Semester’ CHAR(2) NOT NULL,
‘DozentID’ INTEGER)”;
abfrage.execute(befehl);
(Hochkommas bei Bezeichnern, Unterscheidung Gross/KleinSchreibung)
17
Das Paket java.sql
Tupel einfügen:
String befehl =
“INSERT INTO Vorlesung VALUES
(1,‘Informatik 2‘,‘2009‘,‘SS‘,null)”;
abfrage.executeUpdate(befehl);
(Hochkommas bei Zeichenketten, nicht bei Zahlen, nicht bei
null)
18
Das Paket java.sql
Tupel löschen:
String befehl =
“DELETE FROM Vorlesung
WHERE semester = ‘SS’”;
abfrage.executeUpdate(befehl);
19
Das Paket java.sql
Tupel ändern:
String befehl =
“UPDATE Vorlesung
SET DozentID = 13
WHERE ID = 1”;
abfrage.executeUpdate(befehl);
20
Das Paket java.sql
Tupel ausgeben:
String befehl =
“SELECT * FROM Vorlesung”;
ResultSet ergebnis = abfrage.executeQuery(befehl);
21
Das Paket java.sql
Tupel ausgeben:
Schnittstelle ResultSet
A table of data representing a database result set
Maintains a cursor pointing to its current row of data
(initially 1st row)‫‏‬
Default: not updatable, has a cursor that moves forward only.
22
Das Paket java.sql
Tupel ausgeben:
Schnittstelle ResultSet
Vorwärts/Rückwärts durchlaufbar und aktualisierbar machen
durch Aufruf anderer Version von createStatement
unter Benutzung geeigneter Konstanten:
Statement stmt = c.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs=stmt.executeQuery("...");
23
Das Paket java.sql
Tupel ausgeben:
Schnittstelle ResultSet
Operationen zur Positionierung des Cursors:
boolean absolute(int row)
void moveToInsertRow()
void moveToCurrentRow()
boolean first()
boolean last()
boolean next()
boolean previous()
24
Das Paket java.sql
Tupel ausgeben:
Schnittstelle ResultSet
Operationen, um Daten zu lesen (für jeden Datentyp):
boolean getBoolean(int columnIndex)
boolean getBoolean(String columnName)
...
25
Das Paket java.sql
Tupel ausgeben:
Schnittstelle ResultSet
Operationen, um Daten zu aktualisieren (für jeden Datentyp):
void
...
void
void
void
updateBoolean(int columnIndex, boolean x)
insertRow()
updateRow()
deleteRow()
26
Das Paket java.sql
Tupel ausgeben:
String befehl =
“SELECT * FROM Vorlesung”;
ResultSet ergebnis = abfrage.executeQuery(befehl);
while (ergebnis.next()){
System.out.println(ergebnis.getString(“Name”));
//oder Operationen zum Erzeugen von Objekten
}
27
Das Paket java.sql
Zusammenfassung des Codes:
Class.forName(“org.apache.derby.jdbc.EmbeddedDriver”);
Connection c = DriverManager.getConnection(
“jdbc:derby:derbyDB;create=true”,””,””);
Statement abfrage = c.createStatement();
String befehl = “SELECT * FROM Vorlesung”;
ResultSet ergebnis = abfrage.executeQuery(befehl);
while (ergebnis.next()){
//Operationen zum Erzeugen von Objekten
}
28
Das Paket java.sql
Zusammenfassung des Codes: Programmabbruch bei Fehler
Klasse nicht
vorhanden
Class.forName(“org.apache.derby.jdbc.EmbeddedDriver”);
Connection c = DriverManager.getConnection(
Kein Treiberzugriff
“jdbc:derby:derbyDB;create=true”,””,””);
Statement abfrage = c.createStatement();
String befehl = “SELECT * FROM Vorlesung”;
ResultSet ergebnis = abfrage.executeQuery(befehl);
Kein
while (ergebnis.next()){
//Operationen zum ErzeugenDatenbankzugriff
von Objekten
}
29
Das Paket java.sql
Zusammenfassung des Codes: Fehler abfangen
try{
Class.forName(“org.apache.derby.jdbc.EmbeddedDriver”);
Connection c = DriverManager.getConnection(
“jdbc:derby:derbyDB;create=true”,””,””);
Statement abfrage = c.createStatement();
String befehl = “SELECT * FROM Vorlesung”;
ResultSet ergebnis = abfrage.executeQuery(befehl);
while (ergebnis.next()){
//Operationen zum Erzeugen von Objekten
}
}catch(Exception e){<Code für Fehlerbehandlung>}
30
Das Paket java.sql
Einfügen in Datenhaltungsschicht: Klassendiagramm
<Container>
daten<Container>
root
DatenContainer
root
<Container>
store
<<interface>>
Datenhaltung
daten<Container>
Datei
31
Das Paket java.sql
Einfügen in Datenhaltungsschicht: Klassendiagramm
+
+
+
+
+
<<interface>>
Datenhaltung
load
save
add
delete
modify
Laden und Speichern aller
Objekte
Speichern, Löschen und
Modifizieren
einzelner Objekte
32
Das Paket java.sql
Einfügen in Datenhaltungsschicht (eine Alternative):
Klassendiagramm
Datei
- DriverClassName :String =...
- databaseUrl :String =...
con :Connection
user :String
password :String
+
+
+
+
+
+
Datei()
load(out con :DatenContainer)
save(in con :DatenContainer)
add(in o :Object)
delete(in o :Object)
modify(in o :Object)
33
Das Paket java.sql
Einfügen in Datenhaltungsschicht (eine Alternative):
Implementierung in Java
public Datei() {
try{
Class.forName(driverClassName);
con = DriverManager.getConnection
(databaseUrl,user,password);
}catch(Exception e){
<Code für Fehlerbehandlung>
}
}
34
Das Paket java.sql
Einfügen in Datenhaltungsschicht (eine Alternative):
Implementierung in Java
public void load(DatenContainer con){
try{
Statement abfrage = con.createStatement();
String befehl = <Select-Ausdruck passend zu Klasse>;
ResultSet ergebnis = abfrage.executeQuery(befehl);
while (ergebnis.next()){
<Objekte erzeugen in Containern über dataCon> }
}catch(Exception e){
<Code für Fehlerbehandlung>
}
}
[Bei mehreren Klassen: viele select-Anweisungen nacheinander]
35
Das Paket java.sql
Daten aus Datenbank laden
AnwendungsGUI starten
In AnwendungsGUI DatenContainer initialisieren
In DatenContainer Objekt-Container initialisieren
In DatenContainer Datei-Objekt store initialisieren
und store.load(this) aufrufen
36
Das Paket java.sql
Einfügen in Datenhaltungsschicht (eine Alternative):
Implementierung in Java
public void add(Oblect o){
try{
Statement abfrage = con.createStatement();
String befehl = <insert-Ausdruck passend zu o>;
abfrage.executeUpdate(befehl);
}catch(Exception e){
<Code für Fehlerbehandlung>
}
}
[Bei mehreren Klassen: Viele alternative insert-Anweisungen]
37
Das Paket java.sql
Neues Objekt in Datenbank speichern
“Speichern”-Button klicken
In actionPerformed(): Objekt erzeugen und in ObjektContainer einfügen
Im Container: Aufruf von root.getStore().add(o)
38
Das Paket java.sql
Verwaltung der Werte der (zusätzlichen) ID-Spalten?
Zusätzliche ID-Attribute in den Fachkonzeptklassen
(Vor-/Nachteile?)
Übernehmen der Werte beim Laden/Abspeichern
Wie stellt man die Eindeutigkeit der ID-Werte sicher?
ID-Attribut in der Fachkonzeptschicht verwenden?
Identifizieren von Tupeln in Tabellen über die ID
39
Das Paket java.sql
Verwaltung der Werte der (zusätzlichen) ID-Spalten?
Keine solchen zusätzlichen Attribute (Vor-/Nachteile?)
Erzeugung der Werte beim Abspeichern (Datenhaltung)
Ignorieren der ID-Werte beim Laden
Wie identifiziert man Tupel in Tabellen?
Wie stellt man die Eindeutigkeit der ID-Werte sicher?
40
Herunterladen