Datenbank-Werte dynamisch ausgeben

RezaScript

Bekanntes Mitglied
Hallo,

ich habe eine Methode geschrieben, welche mir Daten von der Datenbank ausgibt:

Java:
public List<String> getData(String sql, Map column) {
    this.driver();
    try {
        Connection conn = DriverManager.getConnection(this.url);
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);

        List<String> result = new ArrayList<>();
        if (column.containsKey("string")) {
            for (Object i : column.values()) {
                while (rs.next()) {
                    result.add(rs.getString(String.valueOf(i)));
                }
            }
            return result;
        }

    }
    catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

/**
 * Get the driver of MariaDB
 */
private void driver() {
    // Ensure we have mariadb Driver in classpath
    try {
        Class.forName("org.mariadb.jdbc.Driver");
    }
    catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

Und so rufe ich die Methode auf:
Java:
public List<String> getAll() {
    Database databse = new Database();
    HashMap<String, String> columns = new HashMap<>();
    columns.put("string", "name")
    return databse.getData("SELECT * FROM zt_productions.comments", columns);
}
Somit bekomme ich alle Daten aus dem Column "name". Ich möchte nun aber die Werte von mehreren Columns und habe es so probiert:
Java:
    public List<String> getAll() {
    Database databse = new Database();
    HashMap<String, String> columns = new HashMap<>();
    columns.put("string", "comment");
    columns.put("string", "name")
    return databse.getData("SELECT * FROM zt_productions.comments", columns);
}
Ich bekomme aber immer nur die Werte von "name" und nicht alle Werte. Was mache ich falsch?
 

httpdigest

Top Contributor
Eine Map kann nur einen Wert pro selbem Schlüssel speichern:
Java:
HashMap<String, String> columns = new HashMap<>();
columns.put("string", "comment");
columns.put("string", "name")
Hier überschreibst du den Schlüssel "string" mit dem neuen Wert "name". Deine Map hat anschließend genau einen Eintrag ("string" -> "name").
 

httpdigest

Top Contributor
Naja... da dich in der Methode `List<String> getData(String sql, Map column)` sowieso nur String Columns interessieren, kannst du ja einfach ein Set/List übergeben mit den Namen der String Columns, deren Werte du auslesen und zurückliefern möchtest.
 
X

Xyz1

Gast
Ja Spalten haben ja üblicherweise eine Bezeichnung - und diese kannst (als keys) nutzen.
 

RezaScript

Bekanntes Mitglied
@mihe7 ich möchte alle Daten in einer Array oder als JSON ausgeben. Am liebsten hätte ich auch gerne nur einen Parameter, denn im ersten Parameter gebe ich als SQL ja schon mit welche Daten ich benötige.
 

RezaScript

Bekanntes Mitglied
@httpdigest ich hab's jetzt so probiert:

Code:
public List<String> getAll() {
    Database database = new Database();
    List<String> columns = Arrays.asList("comment", "name");
    return database.getData("SELECT * FROM zt_productions.comments", columns);
}

public List<String> getData(String sql, List<String> column) {
    this.driver();
    try {
        Connection conn = DriverManager.getConnection(this.url);
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);

        List<String> result = new ArrayList<>();

            for (String i : column) {
                while (rs.next()) {
                    result.add(rs.getString(String.valueOf(i)));
                }
            }
            return result;


    }
    catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}
Bekomme aber immer noch nur eine Spalte zurück geliefert.
 

httpdigest

Top Contributor
Du holst ja auch immer nur eine Spalte aus einer Zeile/Row:
Java:
while (rs.next()) {
  result.add(rs.getString(String.valueOf(i)));
}
Oder mit anderen Worten: Deine Schleifen haben die falsche Reihenfolge. Zuerst musst du über die Rows iterieren und darin dann über die Spalten. Aktuell machst du es genau anders herum. Denke einfach erstmal darüber nach, was du da genau machst.
 

mihe7

Top Contributor
Eine etwas allgemeinere Lösung könnte etwa so aussehen:

Java:
List<String> getColumnNames(ResultSet rs) throws SQLException {
    ResultSetMetaData rsmd = rs.getMetaData();
    List<String> result = new ArrayList<>();
    for (int i = 1, n = rsmd.getColumnCount(); i <= n; i++) {
        result.add(rsmd.getColumnName(i));
    }
    return result;
}

Map<String, Object> readRow(ResultSet rs, List<String> columnNames) throws SQLException {
    Map<String, Object> row = new HashMap<>();
    for (String name : columnNames) {
        row.put(name, rs.getObject(name));
    }
    return row;
}

void process(ResultSet rs, Consumer<Map<String, Object>> c) throws SQLException {
    List<String> columns = getColumnNames(rs);
    while (rs.next()) {
        c.accept(readRow(rs, columns));
    }
}

void getData(String sql, Consumer<Map<String, Object>> visitor) {
    this.driver();
    try(Connection conn = DriverManager.getConnection(this.url);
            Statement stmt = conn.createStatement();       
            ResultSet rs = stmt.executeQuery(sql)) {
        process(rs, visitor);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
 

RezaScript

Bekanntes Mitglied
@mihe7 danke für deine Mühe, sieht schon mal sehr interessant aus. Könntest du vielleicht kurz bitte beschreiben was das Script gemau macht? Was ich z.B. u.a. nicht verstanden habe ist c.accept(readRow(rs, columns)); und der zweite Parameter von getData().
 

mihe7

Top Contributor
Das Prinzip ist als Visitor Pattern bekannt.

process lässt sich erstmal die Spaltennamen zurückgeben, geht durch das ResultSet und liest jede Zeile in eine Map ein (readRow). Diese Map (=eingelesene Zeile) wird an den übergebenen Consumer (das ist der Visitor) weitergeleitet.

Ein Consumer ist einfach Objekt, das die Consumer-Schnittstelle (https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html) implementiert.

Wenn Du jetzt beispielsweise die Spalte "NAME" aller Zeilen ausgeben willst:

Java:
Consumer<Map<String, Object>> print = new Consumer<>() {
    @Override
    public void accept(Map<String, Object> row) {
        System.out.println(row.get("NAME"));
    }
};

getData("SELECT NAME, VORNAME FROM personen", print);

Da fällt mir auf, dass getData() ein schlechter Name ist... forEachRow wäre besser.

Oder wenn Du per JSON-P ein JSON-Array zusammenbauen willst:
Java:
final JsonArrayBuilder ab = Json.createArrayBuilder();
Consumer<Map<String, Object>> toJson = new Consumer<>() {
    @Override
    public void accept(Map<String, Object> row) {
        ab.add(Json.createObjectBuilder().
            .add("name", row.getOrDefault("NAME", "")
            .build());
    }
};
getData("SELECT NAME, VORNAME FROM personen", toJson);
System.out.println(ab.build().toString());

Statt den Interfaces kannst Du natürlich auch Lambdas verwenden.
 

mihe7

Top Contributor
Ja, das ist das build für das Object.

Was natürlich auch cool wäre, wäre eine Stream-Variante für den ganzen Käse :)
 

mihe7

Top Contributor
Huch, das hab ich übersehen. Hatte es für ab gelesen.
Gut zu wissen, evtl. sollte man das anders formatieren, zumal ich gerade sehe, dass davor eine schließende Klammer fehlt :)

Java:
    public void accept(Map<String, Object> row) {
        JsonObject obj = Json.createObjectBuilder()
                .add("name", row.getOrDefault("NAME", ""))
                .build();
        ab.add(obj);
    }
Wäre es so besser?
 

RezaScript

Bekanntes Mitglied
@mihe7 danke, da ich nicht alles zu 100% verstanden habe, habe ich es versucht auf meine Art zu lösen, was definitiv nicht die beste Lösung ist.

Java:
public List<ArrayList<ArrayList<String>>> getData(String sql, List<String> columns) {
    this.driver();
    try {
        Connection conn = DriverManager.getConnection(this.url);
        Statement stmt = conn.createStatement();
        ResultSet rs = stmt.executeQuery(sql);

        List<ArrayList<ArrayList<String>>> result = new ArrayList<>();

        while (rs.next()) {
            ArrayList<ArrayList<String>> rows = new ArrayList<>();
            for (String column : columns) {
                ArrayList<String> col = new ArrayList<>();
                col.add(column);
                rows.add(col);
            }
            for (ArrayList<String> i : rows) {
                i.add(rs.getString(i.toString().replaceAll("[\\[\\]]", "")));
            }
            result.add(rows);
        }

        return result;

    }
    catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

Ich bekomme nun eine dreidimensionale Array, was auch gut ist. Ich möchte nun aber an alle Werte rankommen, welche den Column "comment" haben.

Java:
for (ArrayList<ArrayList<String>> getRow : getAll()) {
    for(ArrayList<String> getColumn : getRow) {
        for (String getValue : getColumn) {
            System.out.println(getValue);
        }
    }
}

Das gibt mir aber ALLES aus, d.h. Spaltennamen und Werte in allen Spalten. Kann es sein, dass ich das nicht schaffe, weil die innerste Array keine Keys hat, sondern nur Werte? Wenn ja, wie kann ich das ändern?
 

mihe7

Top Contributor
Ich bekomme nun eine dreidimensionale Array, was auch gut ist.
Ich weiß nicht, was daran gut sein soll.

Wenn ich Dich richtig verstehe, willst Du doch nur über einen Spaltennamen auf den Wert zugreifen, richtig? Das macht man mit einer Map. Wenn Du nicht für jede Zeile die Spaltennamen speichern willst, dann schreibst Du Dir halt eine entsprechende Klasse. Die könnte z. B. neben den Werten der Zeile (List) auch eine Map entgegennehmen, die Spaltennamen auf Array-Indizes abbildet.

Mal skizziert:
Java:
public class Row {
    private final Map<String, Integer> columnIndex;
    private final List<String> row;

    public Row(List<String> row, Map<String, Integer> columnIndex) {
        this.row = row;
        this.columnIndex = columnIndex;
    }

    public Set<String> getColumnNames() {
        return Collections.unmodifiableSet(columnIndex.keySet());
    }

    public String get(String columnName) {
        String result = null;
        Integer index = columnIndex.get(columnName);
        if (index != null) {
            result = row.get(index);
        }
        return result;
    }
}

Dann gibst Du halt in Deiner Abfrage eine Liste solcher Row-Objekte zurück:
Java:
public List<Row> getData(String sql, List<String> columns) {
    this.driver();    

    Map<String, Integer> columnIndex = new HashMap<>();
    int ix = 0;
    for (String column : columns) {
        columnIndex.put(column, ix);
        ix++;
    }

    // try-with-resources, um die geoeffneten Objekte wieder zu schliessen!
    try(Connection conn = DriverManager.getConnection(this.url);
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql)) {

        List<Row> result = new ArrayList<>();

        while (rs.next()) {
            List<String> row = new ArrayList<>();
            for (String column : columns) {
                row.add(rs.getString(column.replaceAll("[\\[\\]]", "")));
            }
            result.add(new Row(row, columnIndex));
        }

        return result;
    }
    catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}

Java:
List<Row> result = getAll();
for (Row row : result) {
    for (String columnName : row.getColumnNames()) {
        System.out.println(columnName + ": " + row.get(columnName));
    }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Werte (u.a. Geldbeträge) in Datenbank speichern und Rundungen? Java Basics - Anfänger-Themen 8
B Klassen Doppelte werte Filtern XML, Datenbank und DOM Java Basics - Anfänger-Themen 3
G JTable (Werte aus der Datenbank) Java Basics - Anfänger-Themen 5
I Erste Schritte Einfache Datenbank-Webseite erstellen als Nicht-IT-lerin Java Basics - Anfänger-Themen 24
M Daten aus errechneter Methode in Datenbank(SQLite) schreiben Java Basics - Anfänger-Themen 60
S Best Practice Fragen zu Projektstruktur einer Datenbank-Abfrage-App (MVC) Java Basics - Anfänger-Themen 13
I Element n aus Datenbank Query (JPA / Hibernate) Java Basics - Anfänger-Themen 3
I Passwort in Datenbank speichern um später wieder auszulesen Java Basics - Anfänger-Themen 5
S OOP Java Eingabe in verschiedene Datenbank Tabellen eintragen Java Basics - Anfänger-Themen 7
I H2 Datenbank starten / Daten in File speichern Java Basics - Anfänger-Themen 25
E schneller von der Datenbank abfragen Java Basics - Anfänger-Themen 15
E Datenbank Spalte zusammenzählen Java Basics - Anfänger-Themen 2
R Datenbank Java Basics - Anfänger-Themen 1
I API Key´s in der Datenbank decrypt / encrypten? Java Basics - Anfänger-Themen 23
M Mehrere Datenbank zugriffe über tomee.xml regeln? Java Basics - Anfänger-Themen 1
M Datenbank oder Textdatei? Java Basics - Anfänger-Themen 4
S Datenbank Befehl nach Login Java Basics - Anfänger-Themen 5
S Datenbank Tabelle eine Zeile an einer bestimmten Stelle einfügen Java Basics - Anfänger-Themen 2
M Von der Datenbank zum Textfield Java Basics - Anfänger-Themen 16
R Best Practice Logik in der Datenbank oder in Java? Java Basics - Anfänger-Themen 3
B Frage zu Datenbank Design - Rechnungen, Angebote... und deren Positionen Java Basics - Anfänger-Themen 4
B Datenbank: Entity mit vielen Referenzen? Ansatz so ok? Java Basics - Anfänger-Themen 8
T Datenbank | Welche am Sinnvollsten? Java Basics - Anfänger-Themen 5
S Daten speichern, ohne Datenbank Java Basics - Anfänger-Themen 8
L Daten aus ArrayList in Datenbank durchsuchen Java Basics - Anfänger-Themen 5
M Datenbank in jTable Laden Java Basics - Anfänger-Themen 49
M Datenbank verbindung Java Basics - Anfänger-Themen 19
J Java Verbindung mit mysql Datenbank Java Basics - Anfänger-Themen 3
B Datenbank, aktuelle Ende als Zahl an Label übergeben Java Basics - Anfänger-Themen 7
T Collections Geeignete Collection/Liste/Datenbank Java Basics - Anfänger-Themen 17
B Treetable (rekursive Funktion) aufbauen von Datenbank Java Basics - Anfänger-Themen 4
R Input/Output Verbindung mit mySql-Datenbank Java Basics - Anfänger-Themen 9
D Compiler-Fehler Wert auf Datenbank übertragen und Sleep Thread Java Basics - Anfänger-Themen 3
N (Java) Regristrierung und Login System mit einer Datenbank Java Basics - Anfänger-Themen 5
J Datenbank Zugriff Java Basics - Anfänger-Themen 24
J Mit JSF Formular in Datenbank schreiben Java Basics - Anfänger-Themen 3
DaCrazyJavaExpert Verschiede Aktionen der Datenbank getrennt durchführen Java Basics - Anfänger-Themen 4
DaCrazyJavaExpert Datenbank wird nicht erstellt Java Basics - Anfänger-Themen 31
E Daten gehen nicht in Datenbank Java Basics - Anfänger-Themen 14
C JTable update mit MySQL Datenbank Java Basics - Anfänger-Themen 1
Meeresgott OOP Gui, Logik und Datenbank richtig aufbauen Java Basics - Anfänger-Themen 43
B Schreiben von zu vielen Einträgen in einer Datenbank Java Basics - Anfänger-Themen 9
S Datenbank auf Knopfdruck abfragen Java Basics - Anfänger-Themen 8
M Java als Webanwendung mit Datenbank abfrage Java Basics - Anfänger-Themen 3
N Datenbank mit GUI verbinden - Wie? Java Basics - Anfänger-Themen 5
1 Datenbank in Java Java Basics - Anfänger-Themen 1
M Erste Schritte Java Applet - HTML Seiten auslesen und in Access Datenbank schreiben? Java Basics - Anfänger-Themen 15
J Bücher Datenbank Java Basics - Anfänger-Themen 5
S Best Practice MVC und große Datenmengen aus einer mySQL - Datenbank Java Basics - Anfänger-Themen 24
J Datum und Uhrzeit in Datenbank falsch hinterlegt Java Basics - Anfänger-Themen 13
R Erstversuch Datenbank Java Basics - Anfänger-Themen 6
I Daten speichern ohne Datenbank Java Basics - Anfänger-Themen 20
A Erste Schritte Verbindung zu MySQL Datenbank herstellen Java Basics - Anfänger-Themen 7
T Sql Datenbank - variable übergeben? Java Basics - Anfänger-Themen 8
C Passwörter möglichst sicher in Datenbank speichern Java Basics - Anfänger-Themen 18
W Erste Schritte Exceltabelle in Datenbank übertragen mittels XDEV Java Basics - Anfänger-Themen 7
J GUI mit phpMyAdmin Datenbank verbinden Java Basics - Anfänger-Themen 0
K Erste Schritte Datenbank SQL erklärung Java Basics - Anfänger-Themen 15
B Lokale Datenbank Java Java Basics - Anfänger-Themen 2
Todesbote Int Array mit Hibernate in Datenbank speichern. Java Basics - Anfänger-Themen 2
U Datenbank in Java Java Basics - Anfänger-Themen 8
M Keine Datenbank verbindung Java Basics - Anfänger-Themen 14
N mit Werten aus einer mysql datenbank in java rechnen Java Basics - Anfänger-Themen 17
Q Datenbank nicht über separaten Server Java Basics - Anfänger-Themen 4
B Dateiname in Datenbank schreiben Java Basics - Anfänger-Themen 2
J fortlaufende Objekte durch Variable auswählen; Datenbank Java Basics - Anfänger-Themen 4
S ArrayList in mysql Datenbank speichern Java Basics - Anfänger-Themen 6
C Datenbank - Welche Java Basics - Anfänger-Themen 5
B Java Objektorientierte Datenbank - Assoziation Hilfe Java Basics - Anfänger-Themen 4
G Input/Output Serialisierung oder Datenbank Java Basics - Anfänger-Themen 6
J Erste Schritte Objekte in Datenbank speichern Java Basics - Anfänger-Themen 26
A Android Datenbank gaaanz einfaches Insert geht nicht - warum? Java Basics - Anfänger-Themen 4
L Erste Schritte Datenbank Zugangsdaten sicher? Java Basics - Anfänger-Themen 15
S Input/Output Primzahlen Datenbank Java Basics - Anfänger-Themen 11
B Mit Java-Programm Daten aus MySQL-Datenbank auslesen, lokal und nicht lokal. Java Basics - Anfänger-Themen 10
K Input/Output Datenbank Java Basics - Anfänger-Themen 27
M Datenbank in die Gui Java Basics - Anfänger-Themen 4
J JTable mit Daten aus Datenbank füllen Java Basics - Anfänger-Themen 3
F Erfassung von PCs in eine SQLite-Datenbank über JDBC Java Basics - Anfänger-Themen 9
T Datenbank Abfrage Exception Null Java Basics - Anfänger-Themen 2
M Brauche ich ein Datenbank oder nicht? Java Basics - Anfänger-Themen 6
D JDBC Datenbank fail?! Java Basics - Anfänger-Themen 20
A Problem beim einfügen in eine Datenbank Java Basics - Anfänger-Themen 2
F Classpath Datenbank ... nur wo? Java Basics - Anfänger-Themen 24
H Datenbank suche in kleine Schritte Java Basics - Anfänger-Themen 6
B Personalnummer aus Datenbank Java Basics - Anfänger-Themen 3
M Welche Datenbank? Java Basics - Anfänger-Themen 5
J RadioButtonInhalt in Datenbank übergeben Java Basics - Anfänger-Themen 3
R Datenbank bei Klassenverteilung führt zu NullPointerException Java Basics - Anfänger-Themen 7
J PW von Datenbank wie abspeichern? Java Basics - Anfänger-Themen 2
F Verbindung zu MySql Datenbank Java Basics - Anfänger-Themen 4
MU5T4NG JPasswordField als Hash in Datenbank abspeichern Java Basics - Anfänger-Themen 3
J Kleine Datenbank programmieren Java Basics - Anfänger-Themen 2
J Eigene kleine Datenbank programmieren Java Basics - Anfänger-Themen 2
F Collections Datenbankdaten in einer Map speichern, bearbeiten, sortieren und wieder in Datenbank schreiben Java Basics - Anfänger-Themen 20
T Zugangsdaten für Datenbank in Java-Programm speichern? Java Basics - Anfänger-Themen 5
S Schnittstelle für Datenbank bzw. Dateiformat Java Basics - Anfänger-Themen 2
C ComboBoxModel mit Daten der Datenbank verändern Java Basics - Anfänger-Themen 2
T Datenbank automatisch erzeugen beim ersten Start Java Basics - Anfänger-Themen 6
I Datenbank - nach erster Verbindung keine Verbindung mehr Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben