将投影映射到 DTO 结果集的选项有很多:
使用元组和 JPQL 的 DTO 投影
List<Tuple> postDTOs = entityManager.createQuery("""
select
p.id as id,
p.title as title
from Post p
where p.createdOn > :fromTimestamp
""", Tuple.class)
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of(2016, 1, 1, 0, 0, 0)
.toInstant(ZoneOffset.UTC )))
.getResultList();
assertFalse(postDTOs.isEmpty());
Tuple postDTO = postDTOs.get(0);
assertEquals(
1L,
postDTO.get("id")
);
使用构造函数表达式和 JPQL 的 DTO 投影
List<PostDTO> postDTOs = entityManager.createQuery("""
select new com.vladmihalcea.book.hpjp.hibernate.query.dto.projection.jpa.PostDTO(
p.id,
p.title
)
from Post p
where p.createdOn > :fromTimestamp
""", PostDTO.class)
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
.toInstant( ZoneOffset.UTC ) ))
.getResultList();
您还可以从 JPA 构造函数表达式中省略 DTO 包名称,并通过其简单的 Java 类名(例如 PostDTO)引用 DTO
。
List<PostDTO> postDTOs = entityManager.createQuery("""
select new PostDTO(
p.id,
p.title
)
from Post p
where p.createdOn > :fromTimestamp
""", PostDTO.class)
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
.toInstant( ZoneOffset.UTC ) ))
.getResultList();
使用元组和本机 SQL 查询的 DTO 投影
这个可以从Hibernate 5.2.11获得,所以还有一个升级的理由。
List<Tuple> postDTOs = entityManager.createNativeQuery("""
SELECT
p.id AS id,
p.title AS title
FROM Post p
WHERE p.created_on > :fromTimestamp
""", Tuple.class)
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
.toInstant( ZoneOffset.UTC ) ))
.getResultList();
使用构造函数的 DTO 投影结果
如果我们使用前面介绍的相同类类型,则必须提供以下内容:PostDTO
@SqlResultSetMapping
@NamedNativeQuery(
name = "PostDTO",
query = """
SELECT
p.id AS id,
p.title AS title
FROM Post p
WHERE p.created_on > :fromTimestamp
""",
resultSetMapping = "PostDTO"
)
@SqlResultSetMapping(
name = "PostDTO",
classes = @ConstructorResult(
targetClass = PostDTO.class,
columns = {
@ColumnResult(name = "id"),
@ColumnResult(name = "title")
}
)
)
现在,名为本机查询的 SQL 投影按如下方式执行:
List<PostDTO> postDTOs = entityManager.createNamedQuery("PostDTO")
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 )
.toInstant( ZoneOffset.UTC ) ))
.getResultList();
使用 ResultTransformer 和 JPQL 进行 DTO 投影
这一次,您的 DTO 需要具有需要 Hibernate 从基础 JDBC 填充的属性的 setter。ResultSet
DTO 投影如下所示:
List<PostDTO> postDTOs = entityManager.createQuery("""
select
p.id as id,
p.title as title
from Post p
where p.createdOn > :fromTimestamp
""")
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) ))
.unwrap( org.hibernate.query.Query.class )
.setResultTransformer( Transformers.aliasToBean( PostDTO.class ) )
.getResultList();
使用 ResultTransformer 和本机 SQL 查询的 DTO 投影
List postDTOs = entityManager.createNativeQuery("""
select
p.id as \"id\",
p.title as \"title\"
from Post p
where p.created_on > :fromTimestamp
""")
.setParameter( "fromTimestamp", Timestamp.from(
LocalDateTime.of( 2016, 1, 1, 0, 0, 0 ).toInstant( ZoneOffset.UTC ) ))
.unwrap( org.hibernate.query.NativeQuery.class )
.setResultTransformer( Transformers.aliasToBean( PostDTO.class ) )
.getResultList();