[英]JPA/HIBERNATE: How can Query return Non- Entities Objects or List of Objects with inner non-Entities objects?
[英]Spring Data JPA: How can Query return Non- Entities Objects or List of Objects?
我在我的项目中使用 spring 数据 JPA。 我正在玩数百万条记录。 我有一个要求,我必须为各种表获取数据并构建一个对象,然后在 UI 上绘制它。 现在如何实现我的 Spring 数据存储库。 我读过它可以通过命名本机查询来实现。
如果命名原生查询没有返回实体或实体列表,我们可以使用@SqlResultSetMapping 注解将查询结果映射到正确的返回类型。
但是当我尝试使用@SqlResultSetMapping
它正在使用另一个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 '。 (这个例子我只是为了 POC 目的而尝试执行,实际用例非常复杂,复杂的查询返回不同的结果集)。
如何实现上述用例? 除了使用我的存储库方法返回非实体对象的名称查询之外,还有其他方法吗?
你可以做类似的事情
@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; }
当我第一次遇到这个问题时,我感到非常惊讶,但是,是的,您只能使用 @SqlResultSetMapping 将查询结果映射到标量和托管实体。
我猜你能做的最好的事情就是跳过自动映射。 没有映射的查询将返回List<Object[]>
并且您可以按照您需要的方式映射它。
另一种方法是使用@MappedSuperclass。 表示为@MappedSuperclass(在您的情况下为CustomStudent)的类可以(虽然不确定100%)在@SqlResultSetMapping 中使用。 但是您需要引入继承层次结构,即您的 Student 实体必须扩展 CustomStudent。 从正确的 OO 设计中大部分时间会很糟糕,因为继承会有点人为......
JPA 2.1 ConstructorResult怎么样?
@SqlResultSetMapping(
name="studentPercentile",
classes={
@ConstructorResult(
targetClass=CustomStudent.class,
columns={
@ColumnResult(name="ID"),
@ColumnResult(name="FIRST_NAME"),
@ColumnResult(name="LAST_NAME")
}
)
}
)
@NamedNativeQuery(name="findStudentPercentile", query="SELECT * FROM STUDENT", resultSetMapping="studentPercentile")
我们还可以使用 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());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.