wake-up-neo.com

JPA Query.getResultList () - generische Verwendung

Ich erstelle eine komplexe Abfrage mit mehreren Tabellen und muss das Ergebnis auflisten. Normalerweise verwende ich die EntityManager und ordne das Ergebnis der JPA-Repräsentation zu:

UserEntity user = em.find(UserEntity.class, "5");

Dann kann ich auf alle Werte zugreifen, wenn die Klasse UserEntity sie definiert. Wie kann ich jedoch auf die Feldwerte zugreifen, die von einer systemeigenen Abfrage mit mehreren Tabellen zurückgegeben werden? Was ich bekomme ist eine Liste von Objekten. Das ist soweit gut, aber was ist das Objekt? Array? Karte? Sammlung? ...

//simpleExample
Query query = em.createNativeQuery("SELECT u.name,s.something FROM user u, someTable s WHERE s.user_id = u.id");
List list = query.getResultList();

//do sth. with the list, for example access "something" for every result row.

Ich denke, die Antwort ist ziemlich einfach, aber die meisten Beispiele zeigen nur die Verwendung, wenn direkt in eine targetClass geworfen wird.

PS: In dem Beispiel könnte ich natürlich die Klassenzuordnungen verwenden. In meinem Fall wird someTable jedoch nicht von JPA verwaltet, und daher habe ich weder die Entität noch eine Klassendarstellung davon, und da ich 20 Tabellen beitrete, möchte ich nicht alle erstellen Klassen nur um auf die Werte zuzugreifen.

25
dognose

Allgemeine Regel ist die folgende:

  • Wenn select einen einzelnen Ausdruck enthält und eine Entität ist, ist das Ergebnis diese Entität
  • Wenn select einen einzelnen Ausdruck enthält und ein Primitiv ist, ist das Ergebnis dieses Primitiv
  • Wenn select mehrere Ausdrücke enthält, enthält Object[] die entsprechenden Grundelemente/Entitäten

In Ihrem Fall ist list ein List<Object[]>.

52
axtavt

Seit JPA 2.0 kann eine TypedQuery verwendet werden:

TypedQuery<SimpleEntity> q = 
        em.createQuery("select t from SimpleEntity t", SimpleEntity.class);

List<SimpleEntity> listOfSimpleEntities = q.getResultList();
for (SimpleEntity entity : listOfSimpleEntities) {
    // do something useful with entity;
}
33
gprest

Die obige Abfrage gibt die Liste von Object [] zurück. Wenn Sie also u.name und etwas von der Liste abrufen möchten, müssen Sie die Werte für die entsprechenden Klassen iterieren und umsetzen.

8
MGPJ

Wenn Sie eine bequemere Methode für den Zugriff auf die Ergebnisse benötigen, können Sie das Ergebnis einer beliebig komplexen SQL-Abfrage mit minimalem Aufwand in eine Java-Klasse umwandeln:

Query query = em.createNativeQuery("select 42 as age, 'Bob' as name from dual", 
        MyTest.class);
MyTest myTest = (MyTest) query.getResultList().get(0);
assertEquals("Bob", myTest.name);

Die Klasse muss als @Entity deklariert werden. Dies bedeutet, dass Sie sicherstellen müssen, dass sie eine eindeutige @Id hat. 

@Entity
class MyTest {
    @Id String name;
    int age;
}
6
GFonte

Hier ist das Beispiel, was für mich funktioniert hat. Ich denke, dass die put-Methode in der Entitätsklasse benötigt wird, um SQL-Spalten Java-Klassenattributen zuzuordnen.

    //simpleExample
    Query query = em.createNativeQuery(
"SELECT u.name,s.something FROM user u,  someTable s WHERE s.user_id = u.id", 
NameSomething.class);
    List list = (List<NameSomething.class>) query.getResultList();

Entity-Klasse:

    @Entity
    public class NameSomething {

        @Id
        private String name;

        private String something;

        // getters/setters



        /**
         * Generic put method to map JPA native Query to this object.
         *
         * @param column
         * @param value
         */
        public void put(Object column, Object value) {
            if (((String) column).equals("name")) {
                setName(String) value);
            } else if (((String) column).equals("something")) {
                setSomething((String) value);
            }
        }
    }
0
aborskiy