JDBCTemplate set verschachtelte POJO mit BeanPropertyRowMapper

Gegeben das folgende Beispiel POJO ' s: (unter der Annahme von Get-und Set-Methoden für alle Eigenschaften)

class User {
    String user_name;
    String display_name;
}

class Message {
    String title;
    String question;
    User user;
}

Kann man leicht Abfragen einer Datenbank (postgres in meinem Fall), und füllen Sie eine Liste der Message-Klassen mit einem BeanPropertyRowMapper, wo das db-Feld übereinstimmen, wird die Eigenschaft in der POJO: (Angenommen, die DB-Tabellen die entsprechenden Felder auf die POJO-Eigenschaften).

NamedParameterDatbase.query("SELECT * FROM message", new BeanPropertyRowMapper(Message.class));

Frage ich mich - ist es eine praktische Möglichkeit zum erstellen einer einzelnen Abfrage und /oder erstellen Sie eine Zeile mapper in solch einer Weise, füllen Sie auch die Eigenschaften der inneren 'user' POJO in der Nachricht.

Ist, Einige syntatical Magie, in dem jedes Ergebnis eine Zeile in der Abfrage:

SELECT * FROM message, user WHERE user_id = message_id

Produzieren eine Liste der Message mit dem zugehörigen Benutzer besiedelten


Anwendungsfall:

Letztlich, die Klassen sind wieder vergangen als serialisierte Objekt aus einer Feder-Controller, die Klassen verschachtelt sind, so dass die resultierende JSON /XML hat eine anständige Struktur.

Im moment, ist diese situation behoben ist, indem Sie zwei Abfragen ausführen und die manuelle Einstellung der Benutzer-Eigenschaft jeder Nachricht in einer Schleife. Brauchbar, aber ich Stelle mir eine elegantere Art und Weise möglich sein sollte.


Update : Lösung -

Großes Lob an @Keeling für die inspiration für die Antwort mit der Nutzung der benutzerdefinierten Zeile mapper - Meine Lösung fügt die Zugabe von bean-Eigenschaft ordnet, um die Automatisierung der Feldzuordnungen.

Nachteil ist die Strukturierung der Abfrage, so dass die entsprechenden Tabellennamen-Präfix (allerdings gibt es keine standard-Konvention zu tun, so daß die Abfrage aufgebaut ist programmatisch):

SELECT title AS "message.title", question AS "message.question", user_name AS "user.user_name", display_name AS "user.display_name" FROM message, user WHERE user_id = message_id

Die benutzerdefinierte Zeile mapper erstellt dann mehrere Bohnen-maps und setzt Ihre Eigenschaften in Bezug auf das Präfix der Spalte: (die Verwendung von meta-Daten, um die Spalte name).

public Object mapRow(ResultSet rs, int i) throws SQLException {

    HashMap<String, BeanMap> beans_by_name = new HashMap();

    beans_by_name.put("message", BeanMap.create(new Message()));
    beans_by_name.put("user", BeanMap.create(new User()));

    ResultSetMetaData resultSetMetaData = rs.getMetaData();

    for (int colnum = 1; colnum <= resultSetMetaData.getColumnCount(); colnum++) {

        String table = resultSetMetaData.getColumnName(colnum).split("\\.")[0];
        String field = resultSetMetaData.getColumnName(colnum).split("\\.")[1];

        BeanMap beanMap = beans_by_name.get(table);

        if (rs.getObject(colnum) != null) {
            beanMap.put(field, rs.getObject(colnum));
        }
    }

    Message m = (Task)beans_by_name.get("message").getBean();
    m.setUser((User)beans_by_name.get("user").getBean());

    return m;
}

Wieder, dies mag wie overkill für ein zwei-Klasse einzusteigen, aber die IRL use case beinhaltet mehrere Tabellen mit zig Feldern.

Das code-snippet oben ist gebrochen. Gibt es mehr schließende Klammern zu öffnen lieben. (4 vs 3)
aktualisiert - TY - hoffe, Sie finden es nützlich

InformationsquelleAutor nclord | 2013-05-23

Schreibe einen Kommentar