JPA 2 条件查询投影
JPA 2 Criteria Query Projection
使用 JPA2 条件查询,我们可以将最终结果投射到 DTO(例如)上,如下所示:
query.select(builder.construct( ProductGridDTO.class,
root.get(Productos_.proId),
root.get(Productos_.proAlias),
root.get(Productos_.proNombre),
companies.get(Companias_.ciaNombre),
companies.get(Companias_.ciaId)));
然而,此方法取决于我的 DTO class 中参数的顺序,这是完全错误的。使用旧的(现已弃用)休眠标准 API 我们可以使用投影列表:
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("id"), "id");
projectionList.add(Projections.property("name"), "name");
这与 DTO 的参数顺序无关。
是否可以在 JPA 中使用类似的策略?
我不这么认为,JPA 中的参数顺序必须匹配。这可能是因为,直到 Java 8,参数名称仅在字节码包含调试信息时才可用。我的猜测是大多数 JPA 提供程序最终调用 Constructor.newInstance()
并且这里的参数必须正确排序。
我继续使用 QueryDSL,它提供了更高级别的抽象并解决了这个投影问题。因此,加载实体和 return 所述实体的 DTO 的查询变为:
public List<CompanyDTO> findByCompanyId(String companyId) {
JPAQuery<?> query = new JPAQuery<Void>(em);
QCompany company = QCompany.company;
return query.from(company)
.where(company.companyId.eq(companyId))
.select(Projections.constructor(CompanyDTO.class, company))
.fetch();
}
其中 CompanyDTO 包含公司实体的构造函数。
使用 JPA2 条件查询,我们可以将最终结果投射到 DTO(例如)上,如下所示:
query.select(builder.construct( ProductGridDTO.class,
root.get(Productos_.proId),
root.get(Productos_.proAlias),
root.get(Productos_.proNombre),
companies.get(Companias_.ciaNombre),
companies.get(Companias_.ciaId)));
然而,此方法取决于我的 DTO class 中参数的顺序,这是完全错误的。使用旧的(现已弃用)休眠标准 API 我们可以使用投影列表:
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("id"), "id");
projectionList.add(Projections.property("name"), "name");
这与 DTO 的参数顺序无关。
是否可以在 JPA 中使用类似的策略?
我不这么认为,JPA 中的参数顺序必须匹配。这可能是因为,直到 Java 8,参数名称仅在字节码包含调试信息时才可用。我的猜测是大多数 JPA 提供程序最终调用 Constructor.newInstance()
并且这里的参数必须正确排序。
我继续使用 QueryDSL,它提供了更高级别的抽象并解决了这个投影问题。因此,加载实体和 return 所述实体的 DTO 的查询变为:
public List<CompanyDTO> findByCompanyId(String companyId) {
JPAQuery<?> query = new JPAQuery<Void>(em);
QCompany company = QCompany.company;
return query.from(company)
.where(company.companyId.eq(companyId))
.select(Projections.constructor(CompanyDTO.class, company))
.fetch();
}
其中 CompanyDTO 包含公司实体的构造函数。