我在我的项目中使用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目的执行,实际的用例非常复杂,复杂的查询返回不同的结果集)。
如何实现上述用例?除了使用名称查询之外还有其他方法我的存储库方法返回非实体对象吗?
答案 0 :(得分:24)
当我第一次遇到这个时,我感到非常惊讶,但是,是的,您可以使用@SqlResultSetMapping将查询结果映射到标量和管理实体。
我猜,你能做的最好就是跳过自动映射。没有映射的查询将返回List<Object[]>
,您可以按照需要进行映射。
另一种方法是使用@MappedSuperclass。表示为@MappedSuperclass(在您的情况下为CustomStudent)的类可以(但不确定100%)在@SqlResultSetMapping中使用。但是您需要引入继承层次结构,即您的Student实体必须扩展CustomStudent。这大部分时间都会从正确的OO设计中吸取,因为继承会有点人为......
答案 1 :(得分:24)
您可以执行类似
的操作@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; }
答案 2 :(得分:18)
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")
答案 3 :(得分:0)
我们还可以使用JSON帮助进行解析。
类级别声明。
AssignedStandbyTasks
主要代码。
@Autowired
private EntityManager em;
private ObjectMapper mapper = new ObjectMapper();