Folien

Werbung
Kai Jannaschk || [email protected]
DATENBANKEN UND SWENTWICKLUNG
03.06.2008
JDBC, SQLJ, O/R-Mapping
Motivation
Reine SQL bietet keine intuitive Benutzerschnittstelle
Geringe Möglichkeiten der Ablaufsteuerung und
Bedingungskontrolle
Realisierung von Algorithmen in
Programmiersprachen
Überwachung und Erzwingung von
Integritätsbedingungen in DBMS unterschiedlich
Kai Jannaschk || [email protected]
03.06.2008
Stored Procedure
Kai Jannaschk || [email protected]
03.06.2008
Stored Procedure
Funktionen im DBMS
Kapselung des direkten Zugriffes auf Tabellen durch
Applikationen mgl.
Unterstützt Befehle zur Ablaufsteuerung und/oder
Auswertung von Bedingungen
Vergleichbar mit Makros
Geschwindigkeitsvorteil gegenüber einfachen SQLAnfragen, da Syntaxprüfung und Prüfung auf logische
Korrektheit bei Aufruf nicht mehr nötig und Ablaufplan
bereits im DBMS hinterlegt
Kai Jannaschk || [email protected]
03.06.2008
Aufbau Stored Procedure
create or replace procedure newPart(
pno IN OUT char, thePrice IN OUT NUMBER, part_description IN varchar,
quantity_on_hand IN OUT integer, reorder IN OUT integer )
as newPno CHAR(8); quan integer := 0;
BEGIN
newPno := UPPER(pno);
IF (quantity_on_hand IS NOT NULL) THEN
quan := quantity_on_hand;
END IF;
IF (reorder IS NULL) THEN
reorder := 10;
END IF;
INSERT INTO INVENTORY (PART_NUMBER, DESCRIPTION, PRICE,
QUANTITY_ON_HAND, REORDER_QUANTITY)
VALUES (newPno, part_description, thePrice, quan, reorder);
SELECT PART_NUMBER, PRICE, QUANTITY_ON_HAND,REORDER_QUANTITY
INTO pno, thePrice, quantity_on_hand, reorder
FROM INVENTORY WHERE PART_NUMBER = newPno;
END
Kai Jannaschk || [email protected]
03.06.2008
JDBC
Funktionsweise
Aufbau
Implementierung
Kai Jannaschk || [email protected]
03.06.2008
Schritte
1.
2.
3.
4.
5.
6.
Laden des Treibers
Herstellen einer Verbindung zur Datenquelle
Vorbereiten einer Abfrage
Ausführen einer Abfrage
Auswerten von Ergebnissen
Schließen der Verbindung zur Datenquelle
Kai Jannaschk || [email protected]
03.06.2008
JDBC Driver Types
Kai Jannaschk || [email protected]
03.06.2008
1. Laden des Treibers
JDBC-Treiber Bibliothek mit Implementierung der
Interfaces „java.sql“ und “javax.sql“
Hauptklasse implementiert Interface „java.sql.Driver“
Abschluss des Ladens eines Treibers erfolgt mit
Registrierung des Treibers beim Treibermanager
try {
Class.forName(”com.ibm.db2.jcc.DB2Driver”);
} catch (ClassNotFoundException e) {
// Fehlerbehandlung, falls Klasse nicht
// gefunden wurde
}
Kai Jannaschk || [email protected]
03.06.2008
2. Herstellen einer Verbindung
DB-Verbindung entspricht einem Objekt vom Typ Connection
Dient zur Erzeugung von Statements
Parameter:
URL jdbc:<dialect>://<host>:<port>/<database>:<parameter>
~ ist DBMS spezifisch
Nutzername für DB
Passwort für Nutzer der DB
mgl. Methodenaufrufe
Connection con = DriverManager.getConnection(
String url
String url, String user, String passwd
);
Kai Jannaschk || [email protected]
03.06.2008
3. Vorbereiten einer Abfrage
Kapselung von Abfragen im Objekt Statement
Jede Abfrage in eigenem Statement
Verarbeitung eines Ergebnisses vor Absenden einer neuen Abfrage mit erzeugten
Statement-Objekt
3 Typen von Statements
Einfaches Statement: statisches Statenment; Kompilierung in DBMS zur Laufzeit
PreparedStatement: Vorbereiten eines Statements mit Möglichkeit zur Angabe von
Parametern Prüfung der Gültigkeit von Parameterwerten in DBMS
PreparedStatement stmt = con.preparedStatement(String
Statement stmt = con.createStatement();
sql);
Callable Statement: Aufruf von z.B. Stored Procedures in der DB
CallableStatement stmt = con.preparedStatement(String
sql);
Kai Jannaschk || [email protected]
03.06.2008
4. Ausführen einer Abfrage
Augenmerk auf 2 Fkt.
stmt.executeUpdate(<String sql>); DDL & DML
ResultSet result = executeQuery(<String sql>);
Bsp. preparedStatement:
String sql = „select nachname from Student
where matrikel like ?“;
PreparedStatement stmt =
con.preparedStatement(sql);
stmt.setString(1,’81%‘);
ResultSet result = stmt.executeQuery();
Kai Jannaschk || [email protected]
03.06.2008
5. Auswerten des Ergebnisses
Ergebnismenge i.d.R. forward-only, not updatable
Durchlauf durch Ergebnismenge nach Iterator-Pattern Zeiger auf Tupel der Ergebnismenge
Zugriff auf einzelne Attributwerte des Tupels mittels
get<Standarddatentyp>()
Bsp.:
while (result.next()) {
System.out.println(result.getString(„nachname“));
System.out.println(result.getString(1));
}
Kai Jannaschk || [email protected]
03.06.2008
6. Schließen der Verbindung
Nach Abschluss freigeben der nicht mehr benötigten
Objekte ResultSet, Statement, Connection
result.close();
stmt.close();
con.close();
Kai Jannaschk || [email protected]
03.06.2008
Hinweise
Nutzung von Metadaten
Verarbeitung von Ergebnismengen
Connection.getMetaData(): Informationen über die DB im
Allgemeinen (Tab-Struktur, Prozeduren, …)
ResultSet.getMetaData(): Informationen über Ergebnismenge
(Attributsnamen, Datentypen, …)
Beliebiges Setzen eines Zeigers innerhalb der Ergebnismenge
Änderbarkeit des Ergebnisses
Transaktionen
Standard: jede SQL-Anweisung in eigener Transaktion
Gezieltes Abspeichern bzw. Rollback von DB-Transaktionen
Kai Jannaschk || [email protected]
03.06.2008
SQLJ
Typen
Aufbau
Vergleich zu JDBC
Kai Jannaschk || [email protected]
03.06.2008
Typen von SQLJ
SQLJ Teil 0: Einbettung von SQL in JavaProgrammen mit standardisierter Syntax und
Semantik
SQLJ Teil 1: Implementierung von Prozeduren und
Funktionen in Java zur Speicherung und Ausführung
in DBMS
SQLJ Teil 2: Möglichkeiten zum Ablegen von JavaDatentypen und –Klassen als SQL-Datentyp
Kai Jannaschk || [email protected]
03.06.2008
Aufbau
Kai Jannaschk || [email protected]
03.06.2008
Beispiel
// Erzeugen der Connection via JDBC
// Connection con = DriverManager.getConnection(…);
// Iterator
#sql iterator StudentenItr (String name, String matrikel);
StudentenItr studentenItr;
// Anfrage deklarieren
String matr = „81%“;
#sql studentenItr = {SELECT * FROM Studenten WHERE matrikel like
:matr};
while (studentenItr.next())
System.out.println(studentenItr.name());
studentenItr.close();
Kai Jannaschk || [email protected]
03.06.2008
Vergleich zu JDBC
Vorteile:
Vorkompilierung der Statements Überprüfung vor
Programmlaufzeit
Parameterbinding einfach, da direkter Zugriff auf HOSTVariablen, Funktionen, …
Performanz der Abfrage, da Ausführungsplanerstellung
bereits zur Kompilierung
Nachteile:
SQLJ-Programm muss erst in Java-Programm transformiert
werden Aufwändigere Entwicklung
Schema muss am Anfang eindeutig feststehen
Kai Jannaschk || [email protected]
03.06.2008
O/R-Mapping
Was ist das?
Warum?
Wie?
Kai Jannaschk || [email protected]
03.06.2008
Idee
Kopplung von
objektorientierter PS
und relationaler DB
Füge zwischen
Anwendung und RDBMS
eine zusätzliche
Softwareschicht ein, die
das O/R-Mapping
automatisch und
transparent durchführt
Kai Jannaschk || [email protected]
03.06.2008
O/R-Mismatch
unterschiedliche Paradigmen
OO: Identität, Zustand, Verhalten, Kapselung von
Eigenschaften, Pointer
ER: relationale Algebra (Tabellen, Schlüssel)
Objektidentität (Identifizierung, Gleichheit) und
Objektlebenszyklus (transient vs. persistent)
Kai Jannaschk || [email protected]
03.06.2008
Probleme des O/R-Mapping
Das OO Modell enthält reichere
Strukturierungsmechanismen als das relationale Modell.
Die folgenden Konzepte müssen transformiert werden:
Klassen
Aggregation
Assoziationen
Komposition
Vererbung
Objektidentität (OO vs. ER) und Objektlebenszyklus
(transient vs. persistent)
Kai Jannaschk || [email protected]
03.06.2008
Umsetzung
Einfaches Bsp.:
eine Klasse für Tabelle
+ ein Klassenattribut je Tabellenspalte
=> ein Tupel der Tabelle entspricht einer konkreten
Klasseninstanz
Fremdschlüssel in Relationen werden zu
Objektassoziationen Problem des „Lazy
Loadings“
Kai Jannaschk || [email protected]
03.06.2008
Hibernate
Kai Jannaschk || [email protected]
03.06.2008
Aufbau von Hibernate
Kai Jannaschk || [email protected]
03.06.2008
Objektlebenszyklus
Kai Jannaschk || [email protected]
03.06.2008
Von der Tab zum POJO
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
3.0//EN“ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hib.Vorlesung" table="VORLESUNG" schema="VL">
<id name="vlnr" type="java.lang.String">
<column name="VLNR" length="10" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" length="40" not-null="true" />
</property>
<property name="stunden" type="java.lang.Long">
<column name="STUNDEN" precision="22" scale="0" not-null="true" />
</property>
</class>
</hibernate-mapping>
Von der Tab zum POJO
public class Vorlesung implements java.io.Serializable {
private static final long serialVersionUID = -433311394853267882L;
private String vlnr;
private String name;
private Long stunden;
/** default constructor */
protected Vorlesung() {
}
/** minimal constructor */
public Vorlesung(String vlnr, String name, Long stunden) {
this.vlnr = vlnr;
this.name = name;
this.stunden = stunden;
}
// Property accessors
public String getVlnr() {
return this.vlnr;
}
protected void setVlnr(String vlnr) {
this.vlnr = vlnr;
}
// …
}
ID-Generatoren
Dienen der Schlüsselerzeugung und damit zur
Bestimmung der Objektidentität in OO bzw. ER
<id name="id" type="long" column="cat_id">
<generator class="org.hibernate.id.TableHiLoGenerator">
<param name="table">uid_table</param>
<param name="column">next_hi_value_column</param>
</generator>
</id>
Generatoren: increment, identity, sequence, hilo,
uuid, assigned, select, foreign
Vererbung: Tab je Klassenhierarchie
1 Tabelle für alle Subklassen
<class name="Payment" table="PAYMENT“>
<id name="id" type="long" column="PAYMENT_ID“>
<generator class="native"/>
</id>
<discriminator column="PAYMENT_TYPE"
type="string"/>
<property name="amount" column="AMOUNT"/>
…
<subclass name="CreditCardPayment" discriminatorvalue="CREDIT“>
…
</subclass>
</class>
Spalten in der Tab der Subklassen dürfen keinen NOT
NULL-Constraint besitzen!
Kai Jannaschk || [email protected]
03.06.2008
Vererbung: Tab je Subklasse
Jede Subklasse eigene Tabelle + eigene Tabelle der Superklasse
<class name="Payment" table="PAYMENT“>
<id name="id" type="long" column="PAYMENT_ID“>
<generator class="native"/>
</id>
<property name="amount" column="AMOUNT"/>
…
<joined-subclass name="CreditCardPayment"
table="CREDIT_PAYMENT“>
<key column="PAYMENT_ID"/>
…
</joined-subclass>
</class>
Primärschlüssel der abhängigen Tabs sind gleichzeitig Fremdschlüssel auf
Superklasse
Superklasse implementiert als Abstract Class
Entspricht XOR von (H)ERM
Kai Jannaschk || [email protected]
03.06.2008
Vererbung: Tab je konkreter Klasse
Jede Subklasse als eigene Klasse
<class name="CreditCardPayment" table="CREDIT_PAYMENT“>
<id name="id" type="long" column="CREDIT_PAYMENT_ID“>
<generator class="native"/>
</id>
<property name="amount" column="CREDIT_AMOUNT"/>
…
</class>
Eigenschaften der Superklasse in jeder Subklasse
Superklasse ist Interface
Kai Jannaschk || [email protected]
03.06.2008
Collections
Unterstützung der Persistierung von Map, Set,
SortedMap, SortedSet, List
List benötigt ein spezielles Sortierattribut (index)
Speichern von neuen Objekten in assoziierten
Collections mit Speicherung des Eigner-Objektes
mgl.
Bidirektionale Assoziation vs. Unidirektionale
Assoziation
Kai Jannaschk || [email protected]
03.06.2008
Abfragesprachen
HQL
Ähnlich SQL
Objektorientierte Abfragesprache
Criteria Query
Abfrage weniger mächtig als HQL
Dynamische Entwicklung von Abfragen (keine einfache
Stringmanipulation)
Geringe Unterstützung von Projektion u. Aggregation
SQL (Migrationsmöglichkeit)
Kai Jannaschk || [email protected]
03.06.2008
Anforderungen
Die Hibernate-Bibliothek
Hibernate-Config-File
Mapping entweder per eigener xml-Datei oder per
Annotation in Java-Klasse
Klassen sind serialisierbar
Jede zu persistierende Klasse benötigt einen DefaultKonstruktor
Für jedes Klassenattribut muss es entsprechende set() +
get() bzw. is()-Methoden geben
Kai Jannaschk || [email protected]
03.06.2008
Probleme und Gefahren
Schlechte Unterstützung von zusammengesetzten
Schlüsseln in Hibernate
Hoher Einmalaufwand zur Erstellung der ganzen
Umgebung (Mapping, POJOs, DAOs)
Wo modelliere ich die Integritätsbedingungen, und
überwache sie?
OO-Design beeinflusst ER-Modellierung
SQL-Abfragen werden implementiert (all-Quantor)
Quellen
www.hibernate.org
„Hibernate in Action“
CHRISTIAN BAUER, GAVIN KING
ISBN 1932394-15-X
Natürlich viele weitere Quellen im www
Kai Jannaschk || [email protected]
03.06.2008
Herunterladen