Подтвердить что ты не робот

JPA Query.getResultList() - используется в общем виде

Я создаю сложный запрос с несколькими таблицами и должен перечислять результат. Обычно я использую EntityManager и сопоставляю результат с JPA-представлением:

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

Затем я могу получить доступ ко всем значениям, так как это определяет класс пользователя UserEntity. Но как я могу получить доступ к значениям полей, возвращенным из собственного запроса с несколькими таблицами? Я получаю список объектов. До сих пор это прекрасно, но что такое "этот"? Массив? Карта? Коллекция?...

//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.

Я думаю, ответ довольно прост, но большинство примеров там просто показывают использование при прямом нажатии на targetClass.

PS: В этом примере я мог бы, конечно, использовать сопоставления классов. Но в моем случае someTable не управляется JPA, и поэтому у меня нет объекта и у меня нет его представления класса, и поскольку я присоединяюсь к 20 таблицам, я не хочу создавать все классы просто для доступа к значениям.

4b9b3361

Ответ 1

Общее правило следующее:

  • Если select содержит одиночное выражение, и это объект, то результатом является то, что entity
  • Если select содержит одно выражение, а это примитив, то результатом является то, что примитивный
  • Если select содержит несколько выражений, тогда результат Object[] содержит соответствующие примитивы/сущности

Итак, в вашем случае list есть List<Object[]>.

Ответ 2

Так как JPA 2.0 a TypedQuery может использоваться:

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;
}

Ответ 3

Вышеприведенный запрос возвращает список Object []. Поэтому, если вы хотите получить u.name и s.something из списка, вам нужно выполнить итерацию и применить эти значения для соответствующих классов.

Ответ 4

Если вам нужен более удобный способ доступа к результатам, он может с легкостью преобразовать результат произвольно сложного SQL-запроса в класс Java:

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);

Класс должен быть объявлен как @Entity, что означает, что вы должны убедиться, что он имеет уникальный @Id.

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

Ответ 5

Вот пример того, что сработало для меня. Я думаю, что метод put необходим в классе сущности для сопоставления столбцов sql с атрибутами класса java.

    //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
    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);
            }
        }
    }