datenbank-programmierung

Was ist JDBC?

Eigenschaften

From https://docs.oracle.com/javase/8/docs/

Treibertypen

Quelle abgerufen am 28.02.2021

Typ 1

Quelle

Typ 2

Typ 3

Typ 4

Wichtige Klassen

import java.sql.*:
/*
  DriverManager
  Connection
  Statement, PreparedStatement
  ResultSet
  ResultSetMetadata
  SQLException
*/

Programmierung

Quelle

Verbindung herstellen

String url = String.format("jdbc:postgresql://localhost:5432/postgres?currentSchema=%s", "schema_name");
Properties props = new Properties();
props.setProperty("user", "postgres");
props.setProperty("password", "1234");

// create the connection
Connection conn = DriverManager.getConnection(url, props);

// ... use the connection ...

// free the connection
conn.close();

Statement ausführen

// ...
Statement stmt = conn.createStatement();
String sql = "SELECT * FROM emp_employee";
ResultSet rs = stmt.executeQuery(sql);
// ...

Resultat auswerten

while (rs.next()) {
    Integer id = rs.getInt(emp_id);
    String email = rs.getString(2);
}

Abfragen der Datenwerte mit

getXXX(Position | Spaltenname), wobei XXX ein passender Java Datentyp ist.

getString(…) funktioniert für alle Spaltentypen.

Cursor Konzept

Das Resultat der DB wird mit einem Cursor durchlaufen.

Problem: Kopplung von SQL und Programmiersprache durch unterschiedliche Datenstrukturen (Relation vs. Tupel)

Lösung: Cursor als Iterator über die verschiedenen Tupel (Tupel enthält eine Liste an Elementen)

Beispiel: Rowcount

Statement stmt = conn.createStatement();
String sql = "SELECT COUNT(*) AS rowcount FROM emp_employee";
ResultSet rs = stmt.executeQuery(sql);
rs.next();
int count = rs.getInt(1);
// ODER: int count = rs.getInt("rowcount");
rs.close();

Fehlerbehandlung

Alle JDBC relevanten Funktionen können Fehler werfen und müssen entsprechend abgefangen werden.

SQLException wird für alle SQL und DBMS Fehler geworfen und muss entsprechend behandelt werden.

try {
    // JDBC Methoden
} catch (SQLException e) {
    e.printStackTrace();
}

Resourcenfreigabe

Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
String sqj = "SELECT COUNT(*) AS rowcount FROM emp_employee";

ResultSet rs = stmt.executeQuery(sql);

// ... Abfrageauswertung

rs.close();
stmt.close();
conn.close();

Das Resultat Set, die Anweisung (Statement) und die Verbindung sollte immer am Ende einer Auswertung geschlossen werden. Ansonsten werden die Ressourcen nicht direkt freigegeben.

SQL Injection

Mit Statement.executeQuery(..) kann bösartiger Code in die Query gelangen.

String id = "1 OR 1=1"; // 1=1 is injected code and the query will return all results

// ... id is a function parameter
ResultSet rs = stmt.executeQuery("SELECT * FROM favorite_number WHERE id = " + id);
// ...

Prepared Statements

Mit PreparedStatements können sichere Abfragen gestaltet werden.

PreparedStatement preparedStmt =
conn.prepareStatement("SELECT * FROM emp_employee WHERE emp_email = ?");
preparedStmt.setString(1, employeeEmail);
ResultSet rs = preparedStmt.executeQuery();

Übungen

Übungen finden sich in projects/jdbc/uebungen.md.