studyklar
IProg · Klausur 3 · Aufgabe 10

JDBC-Methode tuwas: Fehler finden und verbessern

Eine Methode aus einem Servlet, die funktioniert, aber gefährlich gebaut ist. Erst wird gelesen, was sie tut, dann werden die Fehler benannt und behoben. Mit Weiter geht es Schritt für Schritt voran.

Die Aufgabe

10) JDBC: Gegeben sei folgende Methode eines Servlets. (12 Punkte)

public static void tuwas (int x[], PrintStream out) {  try {    Connection cn = DBClass.openNewConnection(); // Hilfsklasse    for (int i = 0; i < x.length; i++) {      String query = "SELECT * FROM Auftritt WHERE anr=" + x[i];      Statement s = cn.createStatement();      ResultSet rs = s.executeQuery(query);      while (rs.next()) {        out.println(rs.getString("ort")+","+rs.getDate("datum"));        String de = "DELETE FROM Buchung WHERE anr=" + x[i];        if ( check(rs.getInt("dauer" )) ) {          Statement s2 = cn.createStatement();          s2.executeUpdate(de);        }      }    }  } catch (Exception e) {    System.out.println("Error: "+ e);  }}

a) Welche Informationen können Sie dem Code entnehmen? Welche Aufgabe erfüllt diese Methode?

b) Welchen unbedingt zu vermeidenden Fehler enthält der angegebene Code?

c) Darüber hinaus hat der Entwickler eine ganze Reihe weiterer unschöner/problematischer Dinge im Code eingebaut. Welche?

d) Lösen Sie das Problem etwas besser! – Die Schnittstelle der Methode muss aber erhalten bleiben. Es sollen auch keine weiteren Methoden/Klassen erzeugt werden.

JDBC (Java Database Connectivity) ist die Java-Schnittstelle zu Datenbanken. Die Methode benutzt drei ihrer Typen: Connection (Verbindung), Statement (Anweisung) und ResultSet (Ergebnis einer Abfrage).

Gefragt ist: (a) was die Methode tut, (b) ihr schlimmster Fehler, (c) weitere Schwächen, (d) eine bessere Fassung mit demselben Kopf und ohne neue Methoden oder Klassen.

Zwei kleine Abweichungen von der Musterlösung in (d): Die Ausgabe bleibt bei "," wie im Original (die Musterlösung schreibt ", "), und gefangen wird nur SQLException statt Exception. Beides ist in Schritt 15 und 16 begründet.

Merke: Fremden JDBC-Code prüft man in drei Fragen: Was wird geöffnet und wieder geschlossen? Wie entsteht der SQL-Text? Was passiert bei einem Fehler?
  1. Den Code von oben nach unten lesen.
  2. Den schwersten Fehler benennen.
  3. Weitere Schwächen sammeln.
  4. Die Methode neu schreiben.

Was der Code verrät

public static void tuwas (int x[], PrintStream out) {  try {    Connection cn = DBClass.openNewConnection(); // Hilfsklasse

Auch ohne Datenbank kann man viel ablesen:

  • x ist ein Array von ganzen Zahlen, Nummern von Auftritten. out ist das Ziel der Ausgabe.
  • DBClass.openNewConnection() ist eine Hilfsklasse, die eine neue Verbindung liefert.
  • Tabelle Auftritt mit den Spalten anr, ort, datum und dauer.
  • Tabelle Buchung mit einer Spalte anr: Buchungen gehören zu einem Auftritt.
  • check bekommt die Dauer als Zahl und liefert true oder false.

Für jede Nummer die Auftritte lesen

    for (int i = 0; i < x.length; i++) {      String query = "SELECT * FROM Auftritt WHERE anr=" + x[i];      Statement s = cn.createStatement();      ResultSet rs = s.executeQuery(query);

Die for-Schleife geht durch das Array. Für jede Nummer x[i] baut sie einen SQL-Text, der alle Auftritte mit dieser Nummer sucht. executeQuery führt ihn aus und liefert ein ResultSet.

Noch 15 Schritte bis zum Ergebnis
Den ganzen Lösungsweg sehen Studierende und Lehrende der HS KL. Registriere dich mit deiner Adresse @stud.hs-kl.de oder @hs-kl.de, dann geht es hier direkt weiter.

Abbildung 1(a) Was die Methode tut

public static void tuwas (int x[], PrintStream out) {  try {    Connection cn = DBClass.openNewConnection(); // Hilfsklasse    for (int i = 0; i < x.length; i++) {      String query = "SELECT * FROM Auftritt WHERE anr=" + x[i];      Statement s = cn.createStatement();      ResultSet rs = s.executeQuery(query);      while (rs.next()) {        out.println(rs.getString("ort")+","+rs.getDate("datum"));        String de = "DELETE FROM Buchung WHERE anr=" + x[i];        if ( check(rs.getInt("dauer" )) ) {          Statement s2 = cn.createStatement();          s2.executeUpdate(de);        }      }    }  } catch (Exception e) {    System.out.println("Error: "+ e);  }}
LegendeDie Methode tuwas, wie sie in der Klausur steht.