Wie greift man in Java auf eine Datenbanktabelle zu?

Java stellt eine Vielzahl von Klassen bereit, um auf alle gängigen Datenbanktypen zugreifen zu können. Wir erarbeiten hier ein Beispiel anhand einer MySQL-Datenbank, deren Zugangsdaten über Eingabefenster abgefragt werden.

Zunächst muss jedoch ein Treiber installiert werden, der die Verbindung zum gewünschten DBMS1 herstellt. Die gängigen Linux-Distributionen stellen diesen bereit, er kann jedoch für MySQL-Datenbanken auch unter http://www.mysql.com heruntergeladen werden. Die Installation selbst sollte problemlos verlaufen, die Einbindung in Java kann gelegentlich Kopfzerbrechen bereiten, weil der Treibername unbekannt ist, bzw. scheint. Man muss nämlich wissen, dass hierunter nichts anderes zu verstehen ist als die Paketstruktur der Treiberklasse innerhalb des Treiber-*.jar-Archivs.
Ein Beispiel: Das Archiv (z.B. unter) /usr/share/java/mysql-connector-java-5.0.4.jar beinhaltet die folgenden Verzeichnisse:

Unter com und org liegt jeweils in einer tieferen Ordnerstruktur ein class-file namens Driver.class. Von diesen beiden muss eines angegeben werden, um mittels Class.forName() zu Beginn unserer Klasse ein Objekt zu bilden:

Class.forName("com.mysql.jdbc.Driver");

Im Konstruktor wird zunächst diese Treiber-Instanz erzeugt. Die folgende Funktionalität wurde in zwei Methoden ausgelagert. Sie werden im Konstruktor aufgerufen.

readDBData(int i) steuert über den int-Parameter die Abfrage der Datenbank-Zugangsdaten. Das Prinzip besteht darin, der Reihe nach die einzelnen benötigten Angaben über Eingabedialoge abzufragen. der int-Parameter steuert hierbei über eine switch-case-Verzweigung welcher Wert erfragt wird. Wird außer beim optionalen Passwort kein Wert angegeben, so wird über eine Rekursion mit identischem Parameter eine erneute Abfrage gestartet. Ansonsten wird die Abfrage forgesetzt.

import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JOptionPane;

public class DBQuery {

    private Connection connection;
    private Statement statement;
    private ResultSet resultSet;
    ArrayList<String[]> result = new ArrayList<String[]>();

    private String host = "";
    private String dbName = "";
    private String dbTable = "";
    private String user = "";
    private String pass = "";

    public DBQuery() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            System.out.println("Fehler bei MySQL-JDBC-Bridge" + e);
            return;
        }

        readDBData(0);

        printDBData(result);

        System.out.println("Anzahl Tupel: " + result.size());
    }

    private void readDBData(int i) {

        switch (i) {
        case 0:
            host = JOptionPane.showInputDialog("Datenbankhost:");
            if (host.equals("")) {
                System.err.println("Bitte einen Datenbankhost angeben!");
                readDBData(i);
            }
            i++;

        case 1:
            dbName = JOptionPane.showInputDialog("Datenbankname:");
            if (dbName.equals("")) {
                System.err.println("Bitte einen Datenbanknamen angeben!");
                readDBData(i);
            }
            i++;

        case 2:
            dbTable = JOptionPane.showInputDialog("Tabelle:");
            if (dbTable.equals("")) {
                System.err.println("Bitte eine Tabelle angeben!");
                readDBData(i);
            }
            i++;

        case 3:
            user = JOptionPane.showInputDialog("Benutzername:");
            if (user.equals("")) {
                System.err.println("Bitte einen Benutzernamen angeben!");
                readDBData(i);
            }
            i++;

        case 4:
            pass = JOptionPane.showInputDialog("Passwort:");
            break;
        }

        try {
            
            String url = "jdbc:mysql://" + host + "/" + dbName;
            connection = DriverManager.getConnection(url, user, pass);
            statement = connection.createStatement();

            String sqlQuery = "SELECT * FROM " + dbTable;
            resultSet = statement.executeQuery(sqlQuery);
            int spalten = resultSet.getMetaData().getColumnCount();
            System.out.println("Anzahl Spalten: " + spalten);

            while (resultSet.next()) {
                String[] str = new String[8];
                for (int k = 1; k <=spalten; k++) {
                    str[k - 1] = resultSet.getString(k);
                }
                result.add(str);
            }

            statement.close();
            connection.close();
        } catch (SQLException e) {
            System.out.println("Fehler bei Tabellenabfrage: " + e);
            return;
        }
    }

    private void printDBData(ArrayList list) {
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            String[] str = (String[]) iter.next();

            for (int i = 0; i < str.length; i++) {
                System.out.print(str[i] + "\t");
            }
            System.out.print(System.getProperty("line.separator"));
        }
    }

    public static void main(String args[]) {
        new DBQuery();
    }
}

In der Folge wird der URL in einer Variablen gespeichert. Die Syntax

String url = "jdbc:mysql://" + host + "/" + dbName;

muss genau beachtet werden. Hier lauert eine häufige Fehlerquelle.
Es folgt der Verbindungsaufbau zur Datenbank.
connection.createStatement() erzeugt ein Statement-Objekt, das SQL-Statements zur Datenbank senden kann. Dies geschieht in der Folge in Form einer einfachen SELECT-Abfrage. Sie kann natürlich prinzipiell durch jede andere SQL-Abfrage ersetzt werden. Die Abfrage liefert ein ResultSet-Objekt, das einen Zeiger vor das erste Tupel (=abgefragte Tabellenreihe) platziert, sodass der Reihe nach alle Tupel mit Hilfe einer Schleife durchlaufen werden können.
Über die Methode getMetaData() kann eine Reihe von Eigenschaften des Abfrageergebnisses - hier die Spaltenzahl - ermittelt werden.
Innerhalb zweier verschachtelter Schleifen werden dann die Feldwerte jedes Tupels in ein String-Array geladen, das dann einem ArrayList-Objekt hinzugefügt wird. Zum Schluss gilt es noch, das Statement und die Datenbankverbindung korrekt zu schließen.

Die Methode printDBData(ArrayList list) nimmt die ArrayList mit den Datenbankwerten als Parameter entgegen. Über diese wird iteriert und Array für Array mit den hier gespeicherten Werten ausgelesen.

1) Database Management System