JDBC - ssw.jku.at

Werbung
JDBC-
Java Database Connectivity
JOHANNES KEPLER UNIVERSITY LINZ
Research and teaching network
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
2
Motivation
Problem: Zugriff auf ein DBMS ist Herstellerabhängig
Anwendung
Anwendung
Anwendung
Pratikum SWE 2
MySQL API
MySQL
SQ
DB2 API
DB2
Oracle API
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
Oracle
3
Motivation
Lösung: Zwischenschicht
MySQL API
Anwendung
JDBC API
JDB
BC
MySQL
DB2 API
DB2
Oracle API
Oracle
JDBC Treiber
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
4
Design
Java Anwendung
JDBC-Treibermanager
JDBC/ODB
C-Brücke
JDBCTreiber
ODBCTreiber
Datenbank
Datenbank
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
6
Treiber
Typ 1: JDBC/ODBC-Brücke
Brü
ücke
ƒ ODBC ist sehr weit verbreitet 9
ƒ Leistung 8
JDBCJDBC
Anwendung
ODBC
DB
ƒ Wartung 8
ƒ Testen, Experimentieren
Client
Server
ƒ kein JDBC Treiber verfügbar
ƒ Windows Plattformen
Typ 2: Partial Java Driver
ƒ konvertiert JDBC Aufruf in DB abhängigen API Aufruf
ƒ schnell, weil API Aufruf kompiliert ist 9
ƒ DB + OS abhängig 8
ƒ Nutzer braucht plattformabhängige API 8
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
A
JDBCP
An
Anw.
I
Client
DB
Server
7
Treiber
Typ 3: Reiner Java Treiber zu Middleware
ƒ Keine plattformabhängigen Treiber am Client 9
ƒ DB unabhängig 9
ƒ Flexibel, mehrere DB möglich 9
ƒ DB abhängiger Code in Middleware
JDBCAnw.
Client
M
W
DB
Server Server
Typ 4: Reiner Java Treiber direkt zur DB
ƒ JDBC in DB spezifische Netzwerkaufrufe verpackt
ƒ Schnell 9
ƒ Keine plattformabhängigen Treiber am Client 9
ƒ Client braucht für verschiedene DB verschiedene
Treiber 8
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
JDBCAnw.
Client
DB
Server
8
Treiberinstallation
Achtung: Ab Version Java 6 nicht mehr nötig!
Download
ƒ http://developers.sun.com/product/jdbc/drivers
ƒ Datenbankhersteller
Installation
ƒ Eintragen
g in den Klassenpfad
p
Registrieren bei Anwendung
ƒ Bei dem Programmstart durch Parameter:
java –Djdbc.drivers=com.mysql.jdbc.Driver <Programm>
ƒ Setzen der Systemeigenschaft
y
g
"jdbc.drivers":
j
System.setProperty("jdbc.drivers", com.mysql.jdbc.Driver");
ƒ Händisches Instanzieren der Treiber-Klasse:
Class.forName("com.mysql.jdbc.Driver");
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
9
Vorgehen
Typisch sind folgende Schritte:
1) Aufbau einer Verbindung zur Datenbank
2) Definition und ausführen von Datenbankkommandos
3) Verarbeiten der Ergebnisse
4) Ressourcen
R
ffreigeben
i b und
dV
Verbindung
bi d
schließen
hli ß
1.) Verbindung deklarieren;
try {
1.)
) Verbindung
bi d
zur Datenquelle
ll anfordern
f d
2.) SQL-Kommandos ausführen
3.) Ergebnis verarbeiten
4.) Ressourcen freigeben
} catch ( SQLException ) {
Exception behandeln
} finally {
try {
4.) Verbindung schließen
} catch (Exception) { Exception behandeln }
}
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
10
Klassen
für Schritt 1) und 4)
ƒ Driver und DriverManager
ƒ Connection
ƒ DataSource
ataSou ce
für Schritt 2)
ƒ Statement
St t
t
ƒ PreparedStatement
ƒ CallableStatement
für Schritt 3)
ƒ ResultSet
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
11
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
12
Verbindungsaufbau
Verbindungsaufbau erfolgt mit
ƒ Url zur Datenbank
ƒ Benutername,
B
t
P
Passwort
t
Datenbank Url
jdbc:<Datenbanktreiber>:<treiberspezifische Angaben>
Beispiele:
ƒ MySql:
jdbc:mysql://<host>:<port>/< Datenbankname>
ƒ JavaDB (Derby):
jdbc:derby:/path/to/Database
jdbc:derby:Database
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
13
DriverManager (1/2)
Achtung: Ab Version Java 6 nicht mehr nötig!
static-Methoden zur Verwaltung der Treiber, Verbindungsaufbau, Settings
Treiberverwaltung
static void registerDriver(Driver driver)
throws SQLException
static void deregisterDriver(Driver driver)
throws SQLException
static Enumeration<Driver> getDrivers()
Registrierung erfolgt üblicherweise im static-Initializers der Driver-Klasse; es
reicht daher, wenn Driverklasse geladen wird.
Beispiel: Registrieren des Treibers durch Laden der Driver-Klasse
Class.forName("com.mysql.jdbc.Driver").newInstance();
l
f
("
l jdb
i
")
()
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
14
DriverManager (2/2)
Verbindungsaufbau über Klasse DriverManager
ƒ mit Url und optional Benutzer und Passwort
ƒ liefert
li f t Connection-Objekt
i
Obj kt
static Connection getConnection(
String url,
String user,
String password)
throws SQLException
static Connection getConnection(String url)
throws SQLException
Beispiel:
String url = "jdbc:odbc:wombat";
Connection con =
DriverManager.getConnection(url,"oboy","12Java");
Settings: LogStream und Timeout
static
static
static
public
Pratikum SWE 2
void setLogWriter(PrintWriter out)
PrintWriter getLogWriter()
void println(String message)
static void setLoginTimeout(int seconds)
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
15
ResultSet.HOLD_CURSORS_OVER_COMMIT
Connection
or ResultSet.CLOSE_CURSORS_AT_COMMIT
Connection ist zentrales Objekt für Verbindung zur Datenbank
ƒ Erzeugen von Statement-Objekten
Statement createStatement() throws SQLException
PreparedStatement prepareStatement(String sql) throws SQLException
CallableStatement prepareCall(String sql) throws SQLException
…
ƒ Zugriff auf Datenbankinformationen (Metadaten)
DatabaseMetaData g
getMetaData() throws SQLException
ƒ Transaktionen (lokale)
void commit() throws SQLException
void rollback() throws SQLException
void setAutoCommit(boolean autoCommit) throws SQLException
ƒ Diverse Settings
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE.
void setReadOnly(boolean readOnly) throws SQLException
void setTransactionIsolation(int level) throws SQLException
void setHoldability(int holdability) throws SQLException
ƒ Schließen
void close() throws SQLException
Pratikum SWE 2
ResultSet.HOLD_CURSORS_OVER_COMMIT
ResultSet.CLOSE_CURSORS_AT_COMMIT
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
16
Beispiel Verbindungsaufbau
public static void main(String[] args) {
String url = "jdbc:derby:c:/Derby/test;create=true";
Connection conn = null;
try {
conn = DriverManager.getConnection(url);
…
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
17
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
18
Erzeugen von Statement-Objekten
Es gibt 3 Arten von Statement-Objekten
ƒ Statement: normale Anweisungen
ƒ PreparedStatement:
d
vorkompilierte
k
ili t St
Statements
t
t mit
it IInput-Parametern
tP
t
ƒ CallableStatement: zur Ausführung von StoredProcedures mit Input- und OutputParametern
Statement-Objekte werden durch Connection erzeugt
Statement createStatement() throws SqlException
Statement createStatement(int resultSetType,
yp , int resultSetConcurrency)
y
throws SQLException
PreparedStatement prepareStatement(String sql) throws SQLException
PreparedStatement prepareStatement(String sql,
int resultSetType,
resultSetType
int resultSetConcurrency,
int resultSetHoldability)
throws SQLException
CallableStatement
ll bl
prepareCall(String
ll(
i
sql)
l) throws
h
SQLException
i
CallableStatement prepareCall(String sql,
int resultSetType,
int resultSetConcurrency,
i
int
resultSetHoldability)
l
ld bili )
throws SQLException;
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
19
Ausführen von Statement-Objekten
Statement-Objekte erlauben die Ausführung von SQL-Anweisungen
SQL-Anweisungen werden als Strings übergeben
3 Methoden zur Ausführung:
ResultSet executeQuery(String sql) throws SQLException
ƒ Ausführung
A füh
von SSELECT-Statements
C S
ƒ liefert ResultSet als Ergebnis
int executeUpdate(String sql) throws SQLException
ƒ Ausführung von UPDATE, INSERT, DELETE, CREATE, …
ƒ Ergebnis
E b i ist
i die
di A
Anzahl
hl d
der geänderten
ä d
Z
Zeilen
il
boolean execute(String
g sql) throws SQLException
ƒ Ausführung von Anweisungen mit mehreren Resultaten
− boolean
Mehrere Ergebnisse
vorhanden throws SQLException
getMoreResults()
getResultSet() throws SQLException
− ResultSet
Zugriff auf Ergebnisse
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
20
PreparedStatement
PreparedStatement sind vorkompilierte Statements (effizienter)
werden mit SQL-Anweisung durch Connection erzeugt
PreparedStatement prepareStatement(String sql) throws SQLException;
können Input
Input-Parameter
Parameter haben
"INSERT INTO test VALUES (?)";
ƒ werden mit ? im SQL-String
Q
g gekennzeichnet
g
und identifiziert durch Position
void set<Type>(int n, <Type> x)
ƒ Setzen mit set-Operationen entsprechenden Typs
void clearParameters()
ƒ Löschen aller Parameterwerte.
Beispiel:
PreparedStatement stat;
stat = con.prepareStatement("INSERT INTO test VALUES (?)");
stat.setString(1,
g
"Hallo");
stat.executeUpdate();
stat.setString(1, "Welt!");
stat.executeUpdate();
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
21
CallableStatement
CallableStatement: Ausführen von Datenbankprozeduren (SQL stored
procedures
SQL-Strings stellen Prozeduraufruf dar:
ƒ Parameterlose Prozedur
{call procedure_name}
ƒ Prozedur:
{call procedure_name[(?, ?, ...)]}
ƒ Funktion:
{? = call procedure_name[(?, ?, ...)]}
Das Setzen der Parameter erfolgt analog zu den PreparedStatements
Output-Parameter
ƒ müssen als solche registriert werden
void registerOutParameter(int parameterIndex, int sqlType)
throws SQLException
ƒ Werte können mit get-Methoden ausgelesen werden
<Type> get<Type>(int parameterIndex) throws SQLException
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
22
Beispiel Statement und PreparedStatement
public static void main(String[] args) {
…
try {
…
java sql Statement stmt = conn.createStatement();
java.sql.Statement
conn createStatement();
stmt.executeUpdate(
"create table Person (id INTEGER PRIMARY KEY, firstname VARCHAR(128), " +
"lastName VARCHAR(128), born INTEGER)");
PreparedStatement pStmt =
conn.prepareStatement("insert into Person values(?, ?, ?, ?)");
pStmt.setInt(1, 1);
pStmt.setString(2, "Hermann");
pStmt.setString(3, "Maier");
Maier );
pStmt.setInt(4, 1971);
pStmt.executeUpdate();
pStmt.setInt(1, 2);
pStmt.setString(2, "Michael");
pStmt setString(3 "Walchhofer");
pStmt.setString(3,
Walchhofer );
pStmt.setInt(4, 1977);
pStmt.executeUpdate();
…
stmt.execute("update
(" d
Person set born=1973
b
where
h
id ")
id=1");
ResultSet rs = stmt.executeQuery("select id, lastName, born from Person");
…
} catch (
(SQLException
Q
p
e)
) {
…
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
23
Batch-Updates
Absetzen mehrerer Update-Kommandos in einem Batch
Î zur Verbesserung der Performanz
Kommandos werden mit
void addBatch(String sqlCmd)
void addBatch()
angefügt
fü t
und mit
int[] executeBatch()
ausgeführt (Rückgabewert sind Anzahl der geänderten Zeilen pro
Update)
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
25
Beispiel Batch-Updates
mit Statement
Statement stmt = conn.createStatement();
stmt.addBatch("insert into Person values(5, 'Mario', 'Scheiber', 1983)");
stmt.addBatch("insert into Person values(6, 'Rainer', 'Schönfelder', 1977)");
int[] upds = stmt.executeBatch();
mit PreparedStatement
PreparedStatement pStmt =
conn.prepareStatement("insert into Person values(?, ?, ?, ?)");
pStmt.setInt(1, 6);
pStmt.setString(2, "Mario");
pStmt.setString(3, "Scheiber");
pStmt.setInt(4, 1983);
pStmt.addBatch();
pStmt.setInt(1, 7);
pStmt.setString(2, "Rainer");
pStmt.setString(3, "Schönfelder");
pStmt.setInt(4, 1977);
pStmt.addBatch();
int[] upds = pStmt.executeBatch();
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
26
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
27
ResultSet
ResultSet stellt die Ergebnistabelle einer Abfrage dar
Es gibt 3 Arten von ResultsSets
ƒ einfache: können nur sequentiell von vorne nach hinten durchlaufen werden
ƒ scrollbare: erlaubt beide Richtungen und Positionierung
ƒ scrollbare und änderbare: erlauben auch Updates
Unterscheidung erfolgt beim Erzeugen des Statements:
Statement
St
t
t createStatement(int
t St t
t(i t resultSetType,
ltS tT
i t resultSetConcurrency)
int
ltS tC
)
throws SQLException
ResultSet.TYPE_FORWARD_ONLY
ResultSet TYPE SCROLL INSENSITIVE
ResultSet.TYPE_SCROLL_INSENSITIVE
ResultSet.TYPE_SCROLL_SENSITIVE
ResultSet.CONCUR_READONLY
ResultSet CONCUR UPDATABLE
ResultSet.CONCUR_UPDATABLE
ResultSet.TYPE_FORWARD_ONLY
- einfacher ResultSet, nur lesend
ResultSet.TYPE_SCROLL_INSENSITIVE - scrollbar, nur lesend
ResultSet.TYPE_SCROLL_SENSITIVE
- scrollbar, erlaubt updates
ResultSet.CONCUR_READONLY
ResultSet CONCUR_UPDATABLE
ResultSet.
CONCUR UPDATABLE
Pratikum SWE 2
- nur lesend
- erlaubt updates
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
28
Sequentieller Zugriff
ResultSet arbeitet mit Cursor auf aktuelle Zeile
ƒ Zugriff mit get-Methoden auf Spaltenwerte der aktuellen Zeile
Typ> get<
Typ
get Type>(int
(int column)
<Typ> get<Type>(String colName)
int findColumn(String colName)
ƒ Weiterschalten auf nächste Zeile mit next
^ boolean next()
− Anspringen
A
i
d
der nächsten
ä h t Z
Zeile
il (b
(begonnen wird
i d vor der
d ersten
t Z
Zeile)
il )
− true solange noch eine gültige Zeile erreicht wurde.
Beispiel:
getString(3) => 25
getString("Name") => Max
findColumn("Nr") => 1
Pratikum SWE 2
next()
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
Nr
1
2
...
Name
Max
Kurt
...
Age
25
27
...
29
Beispiel ResultSet
public static void main(String[] args) {
…
try {
…
ResultSet rs = stmt.executeQuery("select id, lastName, born from Person");
while (rs.next()) {
int nr = rs.getInt(1);
rs getInt(1);
String lastName = rs.getString("lastName");
int born = rs.getInt("born");
System.out.println(nr + ": " + lastName + " born: " + born);
}
} catch (SQLException e) {
…
}
}
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
30
Zugriff mit scrollable ResultSets
ƒ boolean
b l
fi
first()
()
− Erste Zeile im ResultSet.
− true wenn eine gültige Zeile erreicht wurde.
ƒ beforeFirst()
b f
Fi t()
− Vor die erste Zeile im ResultSet.
ƒ boolean last()
− Letzte
L t t Z
Zeile
il iim ResultSet.
R ltS t
− true wenn eine gültige Zeile erreicht wurde.
ƒ afterLast()
− Nach
N h lletzter
t t Z
Zeile
il iim ResultSet.
R ltS t
ƒ boolean absolute(int row)
− Eine Zeile anspringen
row > 0 ... von oben gezählt (1 erste Zeile
Zeile, 2 zweite Zeile,
Zeile ...))
row < 0 ... von unten gezählt (-1 letzte Zeile, -2 vorletzte Zeile, ...)
− true wenn eine gültige Zeile erreicht wurde.
ƒ boolean relative(int rows)
− Überspringen von rows Zeilen
ƒ int getRow()
− Nummer der aktuellen Zeile
ƒ int getRow()
− Springen auf die vorherige Zeile
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
31
Beispiel scrollable ResultSet
Statement scrStmt =
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet scrRs = scrStmt.executeQuery("select id, lastName, born from Person");
// put out rows after 2nd
scrRs.absolute(2);
while (scrRs.next()) {
int nr = scrRs.getInt(1);
String lastName = scrRs.getString("lastName");
int born = scrRs.getInt("born");
System.out.println(nr + ": " + lastName + " born: " + born);
}
// put out rows in reverse order
scrRs.afterLast();
while (scrRs.previous()) {
int nr = scrRs.getInt(1);
String lastName = scrRs.getString(
scrRs getString("lastName");
lastName );
int born = scrRs.getInt("born");
System.out.println(nr + ": " + lastName + " born: " + born);
}
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
32
Updates mit ResultSet
ResultSets und zugrundeliegende Datenquelle kann geändert werden
Änderbare ResultSets erzeugt durch createStatement mit
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
;
void update<Type>(int column, <Type> val)
void update<Type>(String colName, <Type> val)
Änderunungen im ResultSet mit update-Methoden (in aktueller Zeile)
Änderungen in Datenbank mit
updateRow()
d
()
− um Änderung in aktueller Zeile in
Datenquelle zu schreiben
d l t R ()
deleteRow()
− um aktuelle Zeile zu löschen
insertRow()
− um neue Zeile anzufügen
Pratikum SWE 2
Anfügen von neuen Zeilen
• Springen auf spezielle Zeile mit
moveToInsertRow()
• Datenänderungen
g mit Updates
p
• Einfügen mit insertRow()
rs.moveToInsertRow();
rs updateInt(2 3857);
rs.updateInt(2,
…
rs.insertRow();
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
33
Beispiel Update bei ResultSets
Statement updStmt = conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet updRs = updStmt.executeQuery("select id,firstName,lastName,born from Person");
updRs.absolute(3);
while (updRs.previous()) {
int born = updRs.getInt("born");
// decrease born by 1
updRs.updateInt("born", born - 1);
updRs.updateRow();
}
// insert one new row
updRs.moveToInsertRow();
updRs.updateInt(1, 5);
updRs updateString("firstName"
updRs.updateString(
firstName , "Chritoph");
Chritoph );
updRs.updateString("lastName", "Gruber");
updRs.updateInt("born", 1976);
updRs.insertRow();
// delete
d l
fi
first
row
updRs.absolute(1);
updRs.deleteRow();
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
34
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
35
Typen
Standard-Typemapping zwischen SQL und JAVA
SQL Type
Java Type
CHAR, VARCHAR, LONGVARCHAR
String
NUMERIC,, DECIMAL
jjava.math.BigDecimal
g
BIT
boolean
TINYINT
byte
SMALLINT
short
INTEGER
int
BIGINT
long
g
REAL
float
FLOAT, DOUBLE
double
BINARY VARBINARY
BINARY,
VARBINARY, LONGVARBINARY
b t []
byte[]
DATE
java.sql.Date
TIME
java.sql.Time
TIMESTAMP
java.sql.Timestamp
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
36
Java Typ Ö JDBC Typ (PreparedStatement)
JSR 221, JDBC Specification 4, November 7, 2006, Page 198
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
37
JDBC Typ Ö Java Typ (ResultSet)
JSR 221, JDBC Specification 4, November 7, 2006, Page 199
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
38
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
39
Metadaten (1/2)
Zugriff auf Metadaten über Datenbank über Connection-Objekt
DatabaseMetaData getMetaData() throws SQLException
DatabaseMetaData erlaubt Zugriff auf Informationen über Datenbanken
public interface DatabaseMetaData extends Wrapper {
String getDatabaseProductName() throws SQLException;
boolean supportsTransactions() throws SQLException;
ResultSet getProcedures(String catalog, String schemaPattern,
String procedureNamePattern) throws SQLException;
ResultSet getTables(String catalog, String schemaPattern,
String tableNamePattern, String types[]) throws SQLException;
ResultSet getSchemas() throws SQLException;
ResultSet getCatalogs() throws SQLException;
ResultSet getColumns(String catalog, String schemaPattern,
String tableNamePattern, String columnNamePattern) throws SQLException;
ResultSet getPrimaryKeys(String catalog, String schema, String table)
throws SQLException;
…
}
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
40
Metadaten (2/2)
Zugriff über Metadaten über ResultSet
ResultSetMetaData getMetaData() throws SQLException
−
Zugriff
g
auf Spalteninformation
p
String getColumnName(int column)
int g
getColumnType(int
yp (
column)
)
String getColumnTypeName(int column)
String getTableName(int column)
− ...
getColumnCount()
tC l
C
t()
getColumnName(1)
getColumnType(3)
getColumnTypeName(3)
getTableName(2)
tT bl N
(2)
Pratikum SWE 2
=>
=>
=>
=>
=>
3
"Nr"
4
"int"
"
"users"
"
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
41
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
42
Transaktionen
C
Connection
i unterstützt
ü
Transaktionen
ki
Auto Commit:
ƒ Bei AutoCommit ist jjede Anweisung
g eine abgeschlossene
g
Transaktion
ƒ Kann mit setAutoCommit bei Connection ausgeschalten werden
<Connection>.setAutoCommit(boolean autoCommit)
ƒ Abfragen:
boolean <Connection>.getAutoCommit()
Abschliessen einer Transaktion:
<Connection>.commit()
i
i ()
Rücksetzen im Fehlerfall (z.B.: SQLException):
<Connection>.rollback()
Connection conn;
...
try {
conn.setAutoCommit(false);
(
);
Statement stat = conn.createStatement();
stat.executeUpdate("INSERT ...");
stat.executeUpdate("INSERT ...");
stat.executeUpdate("UPDATE ...");
conn commit();
conn.commit();
} catch (SQLException e) {
conn.rollback();
}
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
43
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
44
Zusammenfassung
Datenbankunabhängigkeit
ƒ Zwischenschicht
ƒ Treiberschnittstelle (mind
(mind. SQL 92)
− 4 Treiberarten:
JDBC -> ODBC
Teilweise Java
Nur Java zu einer Middleware
Nur Java zur Datenbank
ƒ Einfachere Programmentwicklung
g
g
Beliebige SQL-Kommandos absetzbar
ƒ Optimierung / Datenbankabhängigkeit
Arten von Statements
ƒ java.sql.Statement
− SStatisch oder vom Benutzer frei wählbar (Achtung:
(
g SQ
SQL injection)
j
)
ƒ java.sql.PreparedStatement
− Vorbereitete Statements (Sicher gegen SQL injection, schnell)
ƒ java.sql.CallableStatement
java sql CallableStatement
− Ausführen von SQL stored procedures
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
45
Weiteres
DataSource als Ersatz für DriverManager (bereits bei JDBC 3.0)
ƒ erlaubt Auffinden von Datenquellen über JNDI
ƒ ermöglicht Connection
Connection-Pooling
Pooling
ƒ ermöglicht verteilte Transaktionen
Neuerungen in JDBC 4.0
4 0 (Java 6.0)
6 0)
ƒ
ƒ
ƒ
ƒ
ƒ
ƒ
Spezifiziert in JSR-221
Automatisches Laden des Treibers beim Verbindungsaufbau
SQL:2003
Unterstützung großer Objekte (CLOB, BLOB)
Mehr Datentypen (SQLXML)
Neue Exceptions
− SQLTransientException
− SQLRecoverableException
− SQLNonTransientException
− …
ƒ Java Datebase Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
46
JDBC
Einführung
Verbindungsaufbau
Datenbankanweisungen
Arbeiten mit ResultSet
Typen
yp
Metadaten
T
Transaktionen
kti
Zusammenfassung
Datenbanksystem Derby
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
47
Derby (Java DB) Installation
Download
ƒ http://www.oracle.com/technetwork/java/javadb/downloads/index.html
Installationsanweisungen
ƒ http://download.oracle.com/javadb/10.6.1.0/getstart/getstartderby.pdf
Umgebungsvariablen
ƒ DERBY_HOME = Pfad zur Derby-Installation
ƒ PATH - Anfügen von bin-Verzeichnis der Derby-Installation
ƒ CLASSPATH – Anfügen von
− %DERBY_HOME%\lib\derby.jar
− %DERBY_HOME%\lib\derbytools.jar
Verzeichnis der DerbyI t ll ti
Installation
>set DERBY_HOME=C:\Programme\Sun\JavaDB\
− C:\Programme\Sun\JavaDB\frameworks\embedded\bin
>set
CLASSPATH=%DERBY_HOME%\lib\derby.jar;%DERBY_HOME%\lib\derbytools.jar;%CLASSPATH%
Systeminformationen
>set
PATH=%DERBY_HOME%\bin;%PATH%
ƒ jjava
org.apache.derby.tools.sysinfo
g p
y
y
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
48
Arbeiten mit Derby
Kommandozeilenwerkzeug
ƒ java org.apache.derby.tools.ij
Verbinden zu, und
erzeugen einer Datenbank
Erzeugen einer Tabelle
Beschreibung einer
Tabelle
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
49
Arbeiten mit Derby
Abf
Abfragen
von
Datensätzen
Aktualisieren eines
Datensatzes
Löschen einer Tabelle
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
50
Derby Eclipse Plug-in
Derby Plug-in für Eclipse
ƒ http://db.apache.org/derby/derby_downloads.html
Zip-files
f l für
fü Plugins
l
ƒ
derby_core_plugin_10.6.2.999685.zip
ƒ
derby_ui_doc_plugin_1.1.2.zip
y
p g
p
in Eclipse-Verzeichnis expandieren
ƒ
Plugins
Derby-Nature in Eclipse hinzufügen
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
51
Derby-Plugin
Menü
Beispielanwendung ij
ij version 10.6
ij> connect 'jdbc:derby:firstdb;create=true';
ij> create table firsttable (id INT primary key, name varchar(12));
0 rows inserted/updated/deleted
ij> insert into firsttable values (10,
(10 'TEN')
TEN ), (29,
(29 'TWENTY')
TWENTY ),(30,
(30 'THIRTY');
THIRTY );
3 rows inserted/updated/deleted
ij> select * from firsttable;
ID
|NAME
-----------------------10
|TEN
29
|TWENTY
30
|THIRTY
3 rows selected
ij> quit;
Pratikum SWE 2
© M. Löberbauer, T. Kotzmann, H. Prähofer, Institut für Systemsoftware, Johannes Kepler Universität Linz
52
Herunterladen