如果您想轻松将您的视图(结果集)映射到实体类中,您可以利用所谓的构造函数表达式,这是JPQL或Criteria API功能之一。
假设你已经定义要么JPQL或标准API查询,例如:
JPQL
SELECT NEW com.dreamer.jpa.VABC(ta.id, SUM(ta.a + tb.b - tc.c), ta.a, tb.b, tc.c)
FROM TableA ta JOIN ta.b tb JOIN tb.c tc
WHERE ta.id = tb.fid AND tb.id = tc.fid
GROUP BY ta.a, tb.b, tc.c
标准API
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<TableA> cq = cb.createQuery(TableA.class);
Root<TableA> ta = c.from(TableA.class);
Join<TableA, TableB> tb = ta.join("b");
Join<TableB, TableC> tc = tb.join("c");
cq.where(cb.and(
cb.equal(ta.get("id"), tb.get("fid")),
cb.equal(tb.get("id"), tc.get("fid"))
)
);
cq.groupBy(ta.get("a"), tb.get("b"), tc.get("c"));
cb.select(cb.construct(com.dreamer.jpa.VABC.class,
ta.get("id"),
cb.diff(cb.sum(ta.get("a"), tb.get("b")), tc.get("c")),
ta.get("a"),
tb.get("b"),
tc.get("c")
)
);
这些查询的结果类型的com.dreamer.jpa.VABC
类,可以定义如下:
package com.dreamer.jpa; //must conform the fully qualified name in the queries
public class VABC {
private int id;
private BigDecimal total;
private BigDecimal a;
private BigDecimal b;
private BigDecimal c;
public VABC(int id,BigDecimal total,BigDecimal a,BigDecimal b,BigDecimal c) {
this.id = id;
// ...
}
}
现在,在执行查询持久性提供(查询处理器)遍历所述查询的结果,并且每个表行被返回,com.dreamer.jpa.VABC
类的新实例使用相匹配的表达类型的构造实例化在查询中列出。
该方法有助于构建用于其他应用层的粗粒度DTO/VO的过程。代替从结果列表中手动构建这样的对象,可以使用单个查询来检索对象的完整列表,即已经准备好推入表示层。
另一种选择是创建一个直接映射到现有数据库视图的实体。因此,你可以选择直接从映射视图:
JPQL
SELECT v FROM VABC v
标准API
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<VABC> cq = cb.createQuery(VABC.class);
Root<VABC> ta = cq.from(VABC.class);
是指数据库视图的实体类可以被定义如下:
@Entity
@Table(name = "V_ABC")
public class VABC {
private Long id;
private BigDecimal total;
private BigDecimal a;
private BigDecimal b;
private BigDecimal c;
public VABC(int id,BigDecimal total,BigDecimal a,BigDecimal b,BigDecimal c) {
this.id = id;
// ...
}
}
将数据库视图直接映射到实体中会产生比构造函数表达式方法更简洁的代码。在这种情况下,基于JPQL/Criteria的查询在查询数据库时产生一个简单的SELECT id, total, a, b, c FROM V_ABC
。
该方法还有助于构建用于其他应用程序层的粗粒度DTO/VO的过程。一个查询返回代表V_ABC视图行的VABC实体实例的完整列表。
谢谢。也只是双重证实,它实际上是视图'V_ABC'的数据库查询,它是否只是JPQL实现'getter'方法从视图查询结果中检索'SELECT total FROM V_ABC ...'? – Dreamer
是的(你制定它有点模糊)。 DB实际上会执行您在定义视图时编写的视图查询/逻辑。 JPA只会获取某种Map fieldName => fieldValue,并将该值设置为相应的Java属性(例如通过调用setter'setTotal()') –