JDBC

Werbung
Tag 5
Inhaltsverzeichnis
ODBC / JDBC: Ziel und Prinzip
JDBC Überblick
Erstes Beispiel
Queries (Execute- und UpdateQuery)
Der Typ "ResultSet"
Diverses
• Metadata
• PreparedStatement
• Transaktionen und Batches
• JavaDB
• JPA / ORM
• Übungen
•
•
•
•
•
•
RDB 5 - 1
Version 3.5
ODBC / JDBC
Prinzipien
Open / Java
"DataBase Connectivity"
Lokaler / ferner
DB-Zugriff
Standardisierte API
Microsoft / Windows
ODBC
Dann Unix
ODBC / JDBC
DBMS Unabhängigkeit
SQL DBs
Treiber basiert
Zugriff auf
Quelle: https://de.wikipedia.org/wiki/Java_Database_Connectivity
Textdatei
Exceldatei
RDB 5 - 2
Version 3.5
JDBC
"Two-tier" Architektur für Datenzugriff
Java Applikation
JDBC
Client Maschine
DBMS-proprietäres Protokoll
DBMS
Quelle: Oracle JDBC Tutorial
Datenbank Server
RDB 5 - 3
Version 3.5
JDBC
"Three-tier" Architektur für Datenzugriff
Java Applet oder
HTML Browser
Client Maschine (GUI)
HTTP, RMI, CORBA, etc...
Java Applikation
Server
JDBC
Server Maschine
(Business Logik)
DBMS-proprietäres Protokoll
DBMS
Quelle: Oracle JDBC Tutorial
Datenbank Server
RDB 5 - 4
Version 3.5
JDBC
Komponenten
• JDBC API
• Teil von JavaSE & JavaEE
• JDBC Driver Manager
• DriverManager
• DataSource + Java Naming and
Directory
Interface (JNDI)
• JDBC Test Suite
• JDBC-ODBC Bridge
RDB 5 - 5
Version 3.5
JDBC
Treiber Typen
Java
Java Application
Application
JDBC
JDBC API
API
Driver
Driver Manager
Manager
JDBC-ODBC
JDBC-ODBC
Bridge
Bridge Driver
Driver
Partial
Partial Java
Java
JDBC
Driver
JDBC Driver
ODBC
ODBC
Client
Client DB
DB Lib
Lib
Pure
Pure Java
Java
JDBC
Driver
JDBC Driver
Pure
Pure Java
Java
JDBC
Driver
JDBC Driver
DB
DB Middleware
Middleware
Client
Client DB
DB Lib
Lib
DB
DB
DB
DB
DB
DB
DB
DB
Type 1
Type 2
Type 3
Type 4
Quelle: https://de.wikipedia.org/wiki/Java_Database_Connectivity
RDB 5 - 6
Version 3.5
JDBC
Connection Pool
RDB 5 - 7
Version 3.5
JDBC Installation
Treiber für MySQL (Connector/J)
• Treiber und Dokumentation auf
https://dev.mysql.com/doc/connector-j/en/connectorj-installing.html
• Debian / Linux Package:
libmysql-java (JDBC-3.0 Type 4 driver)
• CLASSPATH Problem? Eclipse-Lösung
• mysql-connector-java-5.x.xx-bin.jar ins
{projectDir}.lib kopieren
• Configure Build-Path des Projekts
Libraries / add jar und msql-connector addieren
RDB 5 - 8
Version 3.5
JDBC, erstes Beispiel
Treiber laden
public class JdbcTest {
public static void main(String cmdArg[]) {
try {
String mysqlDriver = "com.mysql.jdbc.Driver";
Class.forName(mysqlDriver).newInstance();
// Dies lädt das Treiber...
RDB 5 - 9
Version 3.5
JDBC, erstes Beispiel
Verbindungsaufbau
import java.sql.Connection;
import java.sql.DriverManager;
...
Connection con = DriverManager.getConnection
("jdbc:mysql://localhost/AutorBuch?user=gmaitre&password=Gilles");
RDB 5 - 10
Version 3.5
JDBC, erstes Beispiel
Welcher Port?
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; // in mysql.jar
...
MysqlDataSource ds = new MysqlDataSource();
ds.setServerName("localhost");
ds.setDatabaseName("AutorBuch");
System.out.println("Listening port:" + ds.getPortNumber());
Siehe auch /etc/mysql/my.cnf
RDB 5 - 11
Version 3.5
JDBC, erstes Beispiel
Verbindungsprobleme
Häufige Fehler:
• Error 2003: Can't connect to MySQL server
=> Zugriff nicht möglich, siehe my.cnf
(Problem mit Hostname, Port oder DBName?)
• Error 1130: Host 'xyz' is not allowed to connect to
this MySQL server
=> Siehe mysql.user, Spalte "hostname"
• Error 1045: Access denied for user 'gugus@xyz'
=> Falscher Name oder Passwort ;-)
RDB 5 - 12
Version 3.5
JDBC, erstes Beispiel
Datenzugriff
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery("SELECT PersNr, Name FROM Autor");
while (rs.next()) {
int persNr = rs.getInt("PersNr");
String name = rs.getString("Name");
}
System.out.println
("PersNr: " + Integer.toString(persNr) + ", Name: " + name);
RDB 5 - 13
Version 3.5
JDBC, erstes Beispiel
Ende...
} catch (SQLException e) {
System.out.println("SQLException: " + e.getMessage());
System.out.println("SQLState: " + e.getSQLState());
System.out.println("VendorError: " + e.getErrorCode());
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Key: 12, Name: Kemper
Key: 34, Name: Kofler
Key: 56, Name: Maitre
RDB 5 - 14
Version 3.5
Key: 78, Name: Wall
JDBC
Java, JDBC und MySQL Typen (1)
Quelle: https://dev.mysql.com/doc/ndbapi/en/mccj-using-clusterj-mappings.html
RDB 5 - 15
Version 3.5
JDBC
Java, JDBC und MySQL Typen (2)
Quelle: https://dev.mysql.com/doc/ndbapi/en/mccj-using-clusterj-mappings.html
RDB 5 - 16
Version 3.5
JDBC Grundlagen
ExecuteQuery
/**
* Executes the given SQL statement, which returns a single
* ResultSet object.
*/
ResultSet executeQuery(String sql) throws SQLException;
// Beispiel
ResultSet rs = stm.executeQuery
("SELECT PersNr, Name FROM Autor");
RDB 5 - 17
Version 3.5
JDBC Grundlagen
ExecuteUpdate
/**
* Executes the given SQL statement, which may be an INSERT,
* UPDATE, or DELETE statement or an SQL statement that returns
* nothing, such as an SQL DDL statement.
* @return either
*
(1) the row count for (DML) statements
*
(2) 0 for SQL statements that return nothing
*/
int executeUpdate(String sql) throws SQLException;
// Beispiel
int nbrOfRows = stm.executeUpdate
("update Autor set Vorname='Gilles J.F.' " +
"where Vorname='Gilles';");
RDB 5 - 18
Version 3.5
JDBC Grundlagen
Werte aus einem ResultSet extrahieren
ResultSet rs = stm.executeQuery("SELECT PersNr, Name FROM Autor");
while (rs.next()) {
int key = rs.getInt("PersNr");
String name = rs.getString("Name");
}
ResultSet rs = stm.executeQuery("SELECT PersNr, Name FROM Autor");
while (rs.next()) {
int key = rs.getInt(1);
String name = rs.getString(2);
}
Anderer Weg:
- getString + explizite Konvertierung
- getObject + Casting
RDB 5 - 19
Version 3.5
JDBC Grundlagen
AUTO_INCREMENT Werte finden
/**
* Retrieves any auto-generated keys created as a result of
* executing this Statement object.
* If this Statement object did not generate any keys,
* an empty ResultSet object is returned.
*/
ResultSet getGeneratedKeys() throws SQLException;
RDB 5 - 20
Version 3.5
JDBC Grundlagen
Metadaten
• Wenn "ResultSet" nicht voraussehbar ist
• Mehr hier:
https://docs.oracle.com/javase/7/docs/api/jav
a/sql/ResultSetMetaData.html
• Klasse "ResultSetMetaData" studieren
(Guter Überblick mit Eclipse / JDK SourceCode)
• All what you ever wanted to know about a
"ResultSet"...
• Es gibt auch eine Klasse DatabaseMetaData
RDB 5 - 21
Version 3.5
JDBC Grundlagen
0, null und NULL
• "executeQuery" gibt ein "ResultSet" zurück
• Kann leer sein
• next() verwenden
• In einem "ResultSet" kann ein Element 0 oder NULL
sein
• 0 ist 0 ;-)
• NULL => mit wasNull() testen
RDB 5 - 22
Version 3.5
JDBC Grundlagen
Navigation im ResultSet
• next(), previous()
• first(), last(), isFirst(), isLast()
• beforeFirst(), afterLast()
• getRow()
• absolute(int row) // (1 <=> first; -1 <=> last)
RDB 5 - 23
Version 3.5
JDBC Grundlagen
PreparedStatement (1)
• Wenn Abfrage mehrmals ausgeführt werden muss
• Wird (eventuell) vom Server "vor-kompiliert"
=> effizienter
• 1) Abfrageparameter mit "?" setzen
• 2) Parameter mit Werten setzen und Statement
ausführen
RDB 5 - 24
Version 3.5
JDBC Grundlagen
PreparedStatement (2)
PreparedStatement ps = con.prepareStatement
("SELECT * FROM Autor WHERE Vorname= ? ");
ps.setString(1, "Michael");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String name = rs.getString("Name");
System.out.println("Name: " + name);
}
RDB 5 - 25
Version 3.5
JDBC Grundlagen
Transaktionen
•
•
•
Reihenfolge von zusammengehörigen Operationen
Wechsel zwischen konsistenten Zuständen
Muss ACID-Eigenschaften erfüllen
con.setAutoCommit(false);
Statement stm = con.createStatement();
try {
stm.executeUpdate
("INSERT Autor (PersNr, Name, Vorname) " +
"VALUES (78, 'Wall', 'Larry')");
stm.executeUpdate
("INSERT Autor (PersNr, Name, Vorname) " +
"VALUES (90, 'Schneier', 'Bruce')");
con.commit();
} catch (Exception e) {
e.printStackTrace();
con.rollback(); // Nach Savepoint 'X' wäre möglich
}
RDB 5 - 26
Version 3.5
JDBC Grundlagen
Batches
Effizienter als einzelne Befehle, im Prinzip
Statement stm = con.createStatement();
stm.addBatch("UPDATE
stm.addBatch("UPDATE
stm.addBatch("UPDATE
stm.addBatch("UPDATE
Autor
Autor
Autor
Autor
SET
SET
SET
SET
PersNr='21'
PersNr='43'
PersNr='65'
PersNr='87'
WHERE
WHERE
WHERE
WHERE
PersNr='12'");
PersNr='34'");
PersNr='56'");
PersNr='78'");
int [] changes = stm.executeBatch();
for (int i = 0; i < changes.length; i++) {
System.out.println
("Columns changed by stm: " + i + ": " + changes[i]);
}
RDB 5 - 27
Version 3.5
JDBC Grundlagen
Batches und Transaktionen
con.setAutoCommit(false);
Statement stm = con.createStatement();
try {
stm.addBatch("UPDATE
stm.addBatch("UPDATE
stm.addBatch("UPDATE
stm.addBatch("UPDATE
stm.executeBatch();
con.commit();
} catch (Exception e) {
e.printStackTrace();
con.rollback();
}
Autor
Autor
Autor
Autor
SET
SET
SET
SET
PersNr='12'
PersNr='34'
PersNr='56'
PersNr='78'
WHERE
WHERE
WHERE
WHERE
PersNr='21'");
PersNr='43'");
PersNr='65'");
PersNr='87'");
RDB 5 - 28
Version 3.5
JDBC Grundlagen
Mit BLOBs arbeiten
• In Selbststudium
• Ein gutes Beispiel ist hier zu finden
http://www.java2s.com/Code/Java/Database-SQ
L-JDBC/InsertpicturetoMySQL.htm
RDB 5 - 29
Version 3.5
JavaDB
Ein Überblick
•
Siehe
http://www.oracle.com/technetwork/java/javadb/overview/index.html
•
Praktisch für "kleine" Projekte, die eine SQL-DB brauchen
•
JavaDB = Apache Derby im Java JDK integriert (separates Download)
•
Tools:
• java -jar $DERBY_HOME/lib/derbyrun.jar sysinfo
• java -jar $DERBY_HOME/lib/derbyrun.jar ij
• java -jar $DERBY_HOME/lib/derbyrun.jar dblook -d 'jdbc:derby:firstdb'
RDB 5 - 30
Version 3.5
JPA / ORM
Überblick
Applikation
Relationale Datenbank
Java Persistence API (JPA) / Object-Relation Mapping (ORM)
Mehr dazu im CAS-EADJ
RDB 5 - 31
Version 3.5
Übungen
1) Bringen Sie das Beispiel "JdbcTest" aus den Slides 9 bis 14 zum
Laufen.
a) Laden Sie die AutorBuch Datenbank von hier runter
b) Importieren Sie im MySQL Workbench unter Data Import diese Datei als
"Self Contained File"
c) Laden Sie Java-Beispielsprojekt von hier runter
d) Öffnen Sie im NetBeans mit Open Project… das Java-Beispiel Projekt
e) Lesen Sie die Kommentare am Anfang der Datei JdbcTest.java
2) Erweitern Sie die Klasse "JdbcPlayerMySQL", die die
"JdbcPlayerInterface" für "MeineCD" Datenbank realisiert (siehe
nächste Seite).
Das Java-Projekt zum Herunterladen befindet sich hier
a) Öffnen Sie im NetBeans mit Open Project… das JdbcPlayer Projekt
b) Passen Sie die Klasse "JcbcPlayerMySQL.java an
3) Addieren Sie und ändern Sie Daten in der Datenbank mit JdbcPlayer.
RDB 5 - 32
Version 3.5
Das Programm JdbcPlayer
UML Klassendiagramm
Gezeichnet mit https://cacoo.com/diagrams
RDB 5 - 33
Version 3.5
Das Programm JdbcPlayer
Anwendungsbeispiel
JdbcPlayer Command Interpreter V1.2
----------------------------------Type 'help' to list the commands
JdbcPlayer> help
List of available commands (case-insensitive)
--------------------------------------------connect "<jdbcConnectionString>"
disconnect
show Tables
execute query "<QueryString>"
execute update "<UpdateString>"
exit
help
JdbcPlayer> connect "jdbc:mysql://localhost/AutorBuch?user=...&password=..."
INFO: New connection eshtablished
JdbcPlayer> execute query "select * from Autor"
|--------------------|--------------------|--------------------|
| PersNr
| Vorname
| Name
|
|--------------------|--------------------|--------------------|
| 12
| Alfons
| Kemper
|
| 34
| Michael
| Kofler
|
| 56
| Gilles
| Maitre
|
| 78
| Larry
| Wall
|
|--------------------|--------------------|--------------------|
JdbcPlayer> exit
RDB 5 - 34
Version 3.5
Herunterladen