JPA Query.getResultList() – 以通用方式使用

我正在创建一个包含多个表的复杂查询,需要列出结果。 通常,我正在使用EntityManager并将结果映射到JPA-Representation:

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

然后,我可以访问用户UserEntity类定义它的所有值。 但是,如何访问本机多表查询返回的字段值? 我得到的是一个对象列表。 到目前为止这很好,但对象是什么“是”? arrays? 地图? 采集? …

 //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个表,我不想创建所有的类只是为了访问值。

一般规则如下:

  • 如果select包含单个表达式并且它是一个实体,则result是该实体
  • 如果select包含单个表达式并且它是一个原语,那么result就是该原语
  • 如果select包含多个表达式,则result为包含相应基元/实体的Object[]

因此,在您的情况下, listList

从JPA 2.0 TypedQuery可以使用TypedQuery

 TypedQuery q = em.createQuery("select t from SimpleEntity t", SimpleEntity.class); List listOfSimpleEntities = q.getResultList(); for (SimpleEntity entity : listOfSimpleEntities) { // do something useful with entity; } 

上面的查询返回Object []列表。 因此,如果要从列表中获取u.name和s.something,则需要迭代并为相应的类转换该值。

如果您需要一种更方便的方式来访问结果,则可以将任意复杂的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; } 

这是关于什么对我有用的样本。 我认为在实体类中需要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) 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); } } }