Java SpringDataJPA:查询如何返回非实体对象或对象列表?

Java SpringDataJPA:查询如何返回非实体对象或对象列表?,java,hibernate,jakarta-ee,jpa-2.0,spring-data-jpa,Java,Hibernate,Jakarta Ee,Jpa 2.0,Spring Data Jpa,我在我的项目中使用SpringDataJPA。我在玩数百万张唱片。我有一个需求,我必须获取各种表的数据,构建一个对象,然后在UI上绘制它。现在,如何在我的Spring数据存储库中实现这一点。我已经读到,它可以通过命名的本机查询来实现 如果命名的本机查询未返回实体或 实体,我们可以通过以下方式将查询结果映射到正确的返回类型 使用@SqlResultSetMapping注释 但是,当我试图使用@sqlresultsetmap时,它正在使用另一个entityResult。我的意思是,它只是将一些查询结

我在我的项目中使用SpringDataJPA。我在玩数百万张唱片。我有一个需求,我必须获取各种表的数据,构建一个对象,然后在UI上绘制它。现在,如何在我的Spring数据存储库中实现这一点。我已经读到,它可以通过命名的本机查询来实现

如果命名的本机查询未返回实体或 实体,我们可以通过以下方式将查询结果映射到正确的返回类型 使用@SqlResultSetMapping注释

但是,当我试图使用
@sqlresultsetmap
时,它正在使用另一个entityResult。我的意思是,它只是将一些查询结果转换为实体结果集,但我需要一个非实体对象的结果集

@SqlResultSetMapping(
    name="studentPercentile",
    entities={
        @EntityResult(
           entityClass=CustomStudent.class,
              fields={
                  @FieldResult(name="id", column="ID"),
                  @FieldResult(name="firstName", column="FIRST_NAME"),
                   @FieldResult(name="lastName", column="LAST_NAME")
              }         
        )
   }
) 
@NamedNativeQuery(
    name="findStudentPercentile", 
    query="SELECT * FROM STUDENT", 
    resultSetMapping="studentPercentile")
在上面的示例中,我只是试图将一个结果从学生实体获取到另一个pojo“CustomStudent”中,该pojo不是实体。(这个示例我只是为了POC目的而尝试执行,实际用例非常复杂,复杂的查询返回不同的结果集)


如何实现上述用例?除了使用名称查询,我的存储库方法还会返回非实体对象吗?

当我第一次接触到这一点时,我非常惊讶,但是,是的,您可以使用@sqlresultsetmap将查询结果映射到标量和托管实体

我想,你能做的最好的事情就是跳过自动映射。没有映射的查询将返回
列表
,您可以按需要映射它


另一种方法是使用@MappedSuperclass。表示为@MappedSuperclass的类(在您的例子中是CustomStudent)可以在@SqlResultSetMapping中使用(虽然不是100%)。但您需要引入继承层次结构,即您的学生实体必须扩展CustomStudent。这将占用正确的OO设计的大部分时间,因为继承将有点人为…

您可以执行以下操作

@NamedQuery(name="findWhatever", query="SELECT new path.to.dto.MyDto(e.id, e.otherProperty) FROM Student e WHERE e.id = ?1")
然后MyDto对象只需要一个用正确字段定义的构造函数,即

public MyDto(String id, String otherProperty) { this.id = id; this.otherProperty = otherProperty; }
JPA2.1怎么样


我们还可以使用JSON帮助进行解析

类级声明

@Autowired
private EntityManager em;
private ObjectMapper mapper = new ObjectMapper(); 

主代码

Query query = em.createNativeQuery(argQueryString);
NativeQueryImpl nativeQuery = (NativeQueryImpl) query;
nativeQuery.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List<Map<String,Object>> result = nativeQuery.getResultList();
List<CustomStudent> resultList = result.stream()
   .map(o -> {
         try {
              return 
            mapper.readValue(mapper.writeValueAsString(o),CustomStudent.class);
       } catch (Exception e) {
           ApplicationLogger.logger.error(e.getMessage(),e);
       }
     return null;
    }).collect(Collectors.toList());
Query Query=em.createNativeQuery(argQueryString);
NativeQueryImpl nativeQuery=(NativeQueryImpl)查询;
nativeQuery.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List result=nativeQuery.getResultList();
List resultList=result.stream()
.map(o->{
试一试{
返回
readValue(mapper.writeValueAsString(o),CustomStudent.class);
}捕获(例外e){
ApplicationLogger.logger.error(e.getMessage(),e);
}
返回null;
}).collect(Collectors.toList());

我是否可以编写类似于
选择新路径.to.dto.MyDto(e.id,new path.to.dto.OtherDto)
否的内容,但在MyDto中可以有OtherDto属性,在MyDto的构造函数中,可以使用传递到MyDto构造函数的数据设置OtherDto属性。或者你可以使用@SqlResultsMapping注释。当我写这篇文章时,编译失败,方法公共抽象查询的验证失败。你指的是原始类型吗?你可以使用ConstructorResult。我最近遇到了同样的问题,很高兴看到有人发布了它并得到了解决方案!我们手头有一个类似的问题,我们本应该从三个表中获取记录计数,结果我们使用了SpringJDBCTemplate(尽管通常我们在项目中使用SpringJPAHbernate)。仅仅为了获取记录计数而编写实体等似乎太多了。答案与Hello相同,这听起来不错,但NamedQuery仍然必须附加到实体,而实体是持久化单元的一部分?
Query query = em.createNativeQuery(argQueryString);
NativeQueryImpl nativeQuery = (NativeQueryImpl) query;
nativeQuery.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE);
List<Map<String,Object>> result = nativeQuery.getResultList();
List<CustomStudent> resultList = result.stream()
   .map(o -> {
         try {
              return 
            mapper.readValue(mapper.writeValueAsString(o),CustomStudent.class);
       } catch (Exception e) {
           ApplicationLogger.logger.error(e.getMessage(),e);
       }
     return null;
    }).collect(Collectors.toList());