我正在尝试使用带@ConstructorResult的@SqlResultSetMapping将Native查询的结果映射到POJO。这是我的代码:
@SqlResultSetMapping(name="foo",
classes = {
@ConstructorResult(
targetClass = Bar.class,
columns = {
@ColumnResult(name = "barId", type = Long.class),
@ColumnResult(name = "barName", type = String.class),
@ColumnResult(name = "barTotal", type = Long.class)
})
})
public class Bar {
private Long barId;
private String barName;
private Long barTotal;
...
然后在我的DAO中:
Query query = em.createNativeQueryBar(QUERY, "foo");
... set some parameters ...
List<Bar> list = (List<Bar>) query.getResultList();
我已经读过这个功能仅在JPA 2.1中受支持,但这就是我正在使用的。这是我的依赖:
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
我找到了一些资源,包括这一个:@ConstructorResult mapping in jpa 2.1。但我仍然没有运气。
我错过了什么?为什么不能找到SqlResultSetMapping?
javax.persistence.PersistenceException: org.hibernate.MappingException: Unknown SqlResultSetMapping [foo]
答案 0 :(得分:29)
@SqlResultSetMapping
注释不应放在POJO 上。把它放在(任何)@Entity
课堂上。 “Unknown SqlResultSetMapping [foo]”告诉您,JPA提供程序在名称'foo'下没有看到任何映射。请参阅我的另一个答案以获取正确的示例
答案 1 :(得分:10)
简短的工作示例:
DTO POJO课程
@lombok.Getter
@lombok.AllArgsConstructor
public class StatementDto {
private String authorName;
private Date createTime;
}
存储库bean:
@Repository
public class StatementNativeRepository {
@PersistenceContext private EntityManager em;
static final String STATEMENT_SQLMAP = "Statement-SQL-Mapping";
public List<StatementDto> findPipelinedStatements() {
Query query = em.createNativeQuery(
"select author_name, create_time from TABLE(SomePipelinedFun('xxx'))",
STATEMENT_SQLMAP);
return query.getResultList();
}
@SqlResultSetMapping(name= STATEMENT_SQLMAP, classes = {
@ConstructorResult(targetClass = StatementDto.class,
columns = {
@ColumnResult(name="author_name",type = String.class),
@ColumnResult(name="create_time",type = Date.class)
}
)
}) @Entity class SQLMappingCfgEntity{@Id int id;} // <- workaround
}
答案 2 :(得分:5)
我能够这样做:
Session session = em().unwrap(Session.class);
SQLQuery q = session.createSQLQuery("YOUR SQL HERE");
q.setResultTransformer( Transformers.aliasToBean( MyNotMappedPojoClassHere.class) );
List<MyNotMappedPojoClassHere> postList = q.list();
答案 3 :(得分:3)
将@Entity
添加到DTO POJO的问题在于它将在数据库中创建不需要的表。不得不在必填字段中添加@Id
和瞬态关键字也很麻烦。一个简单的解决方案是将@SqlResultSetMapping
移至抽象类。
@MappedSuperclass
@SqlResultSetMapping(name="foo",
classes = {
@ConstructorResult(
targetClass = Bar.class,
columns = {
@ColumnResult(name = "barId", type = Long.class),
@ColumnResult(name = "barName", type = String.class),
@ColumnResult(name = "barTotal", type = Long.class)
})
})
public abstract class sqlMappingCode {}
不要忘记添加@MappedSuperclass
。这将确保Hibernate自动关联您的映射。
答案 4 :(得分:2)
@Entity
@SqlResultSetMapping(name="ConnexionQueryBean",
entities={
@EntityResult(entityClass=com.collecteJ.business.bean.ConnexionQueryBean.class, fields={
@FieldResult(name="utilisateurId", column="UTILISATEUR_ID"),
@FieldResult(name="nom", column="NOM"),
@FieldResult(name="prenom", column="PRENOM"),
@FieldResult(name="nomConnexion", column="NOM_CONNEXION"),
@FieldResult(name="codeAgence", column="CODE_AGENCE"),
@FieldResult(name="codeBanque", column="CODE_BANQUE"),
@FieldResult(name="codeDevise", column="CODE_DEVISE"),
@FieldResult(name="codeCollecteur", column="CODE_COLLECTEUR")})
})
public class ConnexionQueryBean implements Serializable {
@Id
private long utilisateurId;
private String codeCollecteur;
private String nom;
private String prenom;
private String nomConnexion;
private String codeAgence;
private String codeBanque;
private String codeDevise;
public ConnexionQueryBean() {
}
public long getUtilisateurId() {
return utilisateurId;
}
public void setUtilisateurId(long utilisateurId) {
this.utilisateurId = utilisateurId;
}
public String getCodeCollecteur() {
return codeCollecteur;
}
public void setCodeCollecteur(String codeCollecteur) {
this.codeCollecteur = codeCollecteur;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getNomConnexion() {
return nomConnexion;
}
public void setNomConnexion(String nomConnexion) {
this.nomConnexion = nomConnexion;
}
public String getCodeAgence() {
return codeAgence;
}
public void setCodeAgence(String codeAgence) {
this.codeAgence = codeAgence;
}
public String getCodeBanque() {
return codeBanque;
}
public void setCodeBanque(String codeBanque) {
this.codeBanque = codeBanque;
}
public String getCodeDevise() {
return codeDevise;
}
public void setCodeDevise(String codeDevise) {
this.codeDevise = codeDevise;
}
@Override
public String toString() {
return "ConnexionQueryBean{" + "utilisateurId=" + utilisateurId + ", codeCollecteur=" + codeCollecteur + ", nom=" + nom + ", prenom=" + prenom + ", nomConnexion=" + nomConnexion + ", codeAgence=" + codeAgence + ", codeBanque=" + codeBanque + ", codeDevise=" + codeDevise + '}';
}
这实际上不是一个实体,因为它与任何数据库表都不匹配。但@Entity
和@Id
注释是JPA理解映射的强制措施。如果您真的不想在该类中使用@Entity / @Id
,则可以删除@SqlResultSetMapping
注释并将其放在任何其他实体中,只要JPA可以扫描它。
您还应该确保您的@ComponentScan
内容包含相应的包,如果您使用的是基于Java的弹簧配置,则应在persistence.xml/orm.xml
下的META-INF
明确声明您的实体。目录
这是电话
String connexionQuery = "SELECT u.UTILISATEUR_ID, u.NOM, u.PRENOM, u.NOM_CONNEXION, a.CODE_AGENCE, a.CODE_BANQUE, a.CODE_DEVISE, c.CODE_COLLECTEUR FROM UTILISATEUR u, AGENCE a, COLLECTEUR c "
+ " WHERE (a.CODE_AGENCE = c.CODE_AGENCE AND u.UTILISATEUR_ID = c.UTILISATEUR_ID AND u.NOM_CONNEXION = '"+nomConnextion+"')";
ConnexionQueryBean ConnexionResults = (ConnexionQueryBean) defaultService.getEntityManager().createNativeQuery(connexionQuery,"ConnexionQueryBean").getSingleResult();
System.out.println(ConnexionResults.toString());
我正在使用Spring,JPA 2.1,Hibernate 5和Oracle,我认为这可能不适用于JPA较低版本,找到更多http://www.thoughts-on-java.org/result-set-mapping-complex-mappings/
答案 5 :(得分:0)
QLRM可以替代:http://simasch.github.io/qlrm/
它与特定的JPA实现无关,也适用于JDBC。
答案 6 :(得分:0)
我有一个略有不同的答案,只是从wildloop的答案中得出的。
这是我的答案:
常量类:Constants.java
select
CountryRegionCode]
, [StateProvinceCode]
, COUNT(PSP.StateProvinceID) as [No. of Stores]
from [Sales].[Store] as SS
inner join [Person].[BusinessEntityAddress] as PBEA on SS.BusinessEntityID = PBEA.BusinessEntityID
inner join [Person].[Address] as PA on PBEA.AddressID = PA.AddressID
inner join [Person].[StateProvince] as PSP on PA.StateProvinceID = PSP.StateProvinceID
group by
CountryRegionCode
,StateProvinceCode
having
count(PSP.StateProvinceID) =
(select min(a.cnt)
from (select count(PSP.StateProvinceID) as cnt from [Sales].[Store] as SS2
inner join [Person].[BusinessEntityAddress] as PBEA2 on SS2.BusinessEntityID = PBEA2.BusinessEntityID
inner join [Person].[Address] as PA2 on PBEA2.AddressID = PA2.AddressID
inner join [Person].[StateProvince] as PSP2 on pa2.StateProvinceID = PSP2.StateProvinceID
group by
CountryRegionCode) as a)
order by CountryRegionCode
结果映射类:TestQueryResult.java
public class Constants {
public final String TESTQUERYRESULT_MAPPING_NAME = "TestQueryResultMapping";
}
然后...在我的存储库实现代码中的某个地方:
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.EntityResult;
import javax.persistence.FieldResult;
import javax.persistence.Id;
import javax.persistence.SqlResultSetMapping;
@Getter
@Setter
@SqlResultSetMapping(
//name = "TestQueryResultMapping"
name = Constants.TESTQUERYRESULT_MAPPING_NAME
,entities = @EntityResult(
entityClass = TestQueryResult.class
,fields = {
@FieldResult(name = "rowId", column = "row_id")
,@FieldResult(name = "rowName", column = "row_name")
,@FieldResult(name = "value", column = "row_value")
}
)
)
@Entity
public class TestQueryResult {
@Id
private Integer rowId;
private String rowName;
private String value;
}
...然后中提琴!我得到了一些结果:D!
干杯,
Artanis Zeratul
答案 7 :(得分:0)
这是一个非常常见的问题,因此此答案基于我在博客上写的this article。
让我们考虑我们的数据库中有以下post
和post_comment
表:
SqlResultSetMapping
SqlResultSetMapping
JPA注释如下:
@Repeatable(SqlResultSetMappings.class)
@Target({TYPE})
@Retention(RUNTIME)
public @interface SqlResultSetMapping {
String name();
EntityResult[] entities() default {};
ConstructorResult[] classes() default {};
ColumnResult[] columns() default {};
}
SqlResultSetMapping
注释是可重复的,并在实体类级别上应用。除了采用唯一名称(Hibernate用于注册映射)之外,还有三个映射选项:
EntityResult
ConstructorResult
ColumnResult
接下来,我们将了解这三个映射选项的工作方式,以及需要使用它们的用例。
通过EntityResult
选项,您可以将JDBC ResultSet
列映射到一个或多个JPA实体。
假设我们要获取前5个Post
实体以及与给定PostComment
模式匹配的所有关联title
实体。
正如我在this article中所解释的,我们可以使用DENSE_RANK
SQL Window Function来了解如何过滤post
和post_comment
连接的记录,如下所示以下SQL查询:
SELECT *
FROM (
SELECT
*,
DENSE_RANK() OVER (
ORDER BY
"p.created_on",
"p.id"
) rank
FROM (
SELECT
p.id AS "p.id", p.created_on AS "p.created_on",
p.title AS "p.title", pc.post_id AS "pc.post_id",
pc.id as "pc.id", pc.created_on AS "pc.created_on",
pc.review AS "pc.review"
FROM post p
LEFT JOIN post_comment pc ON p.id = pc.post_id
WHERE p.title LIKE :titlePattern
ORDER BY p.created_on
) p_pc
) p_pc_r
WHERE p_pc_r.rank <= :rank
但是,我们不想返回标量列值的列表。我们要从此查询返回JPA实体,因此我们需要配置entities
批注的@SqlResultSetMapping
属性,如下所示:
@NamedNativeQuery(
name = "PostWithCommentByRank",
query = """
SELECT *
FROM (
SELECT
*,
DENSE_RANK() OVER (
ORDER BY
"p.created_on",
"p.id"
) rank
FROM (
SELECT
p.id AS "p.id", p.created_on AS "p.created_on",
p.title AS "p.title", pc.post_id AS "pc.post_id",
pc.id as "pc.id", pc.created_on AS "pc.created_on",
pc.review AS "pc.review"
FROM post p
LEFT JOIN post_comment pc ON p.id = pc.post_id
WHERE p.title LIKE :titlePattern
ORDER BY p.created_on
) p_pc
) p_pc_r
WHERE p_pc_r.rank <= :rank
""",
resultSetMapping = "PostWithCommentByRankMapping"
)
@SqlResultSetMapping(
name = "PostWithCommentByRankMapping",
entities = {
@EntityResult(
entityClass = Post.class,
fields = {
@FieldResult(name = "id", column = "p.id"),
@FieldResult(name = "createdOn", column = "p.created_on"),
@FieldResult(name = "title", column = "p.title"),
}
),
@EntityResult(
entityClass = PostComment.class,
fields = {
@FieldResult(name = "id", column = "pc.id"),
@FieldResult(name = "createdOn", column = "pc.created_on"),
@FieldResult(name = "review", column = "pc.review"),
@FieldResult(name = "post", column = "pc.post_id"),
}
)
}
)
有了SqlResultSetMapping
,我们可以像这样获取Post
和PostComment
实体:
List<Object[]> postAndCommentList = entityManager
.createNamedQuery("PostWithCommentByRank")
.setParameter("titlePattern", "High-Performance Java Persistence %")
.setParameter("rank", POST_RESULT_COUNT)
.getResultList();
而且,我们可以验证是否正确提取了实体:
assertEquals(
POST_RESULT_COUNT * COMMENT_COUNT,
postAndCommentList.size()
);
for (int i = 0; i < COMMENT_COUNT; i++) {
Post post = (Post) postAndCommentList.get(i)[0];
PostComment comment = (PostComment) postAndCommentList.get(i)[1];
assertTrue(entityManager.contains(post));
assertTrue(entityManager.contains(comment));
assertEquals(
"High-Performance Java Persistence - Chapter 1",
post.getTitle()
);
assertEquals(
String.format(
"Comment nr. %d - A must read!",
i + 1
),
comment.getReview()
);
}
通过SQL存储过程获取JPA实体时,
@EntityResult
也很有用。查看this article了解更多详细信息。
让我们假设要执行一个聚合查询,该查询对每个post_coment
的{{1}}条记录进行计数并返回post
post
以进行报告。我们可以使用以下SQL查询来实现此目标:
title
我们还希望在以下DTO中封装帖子标题和评论数:
SELECT
p.id AS "p.id",
p.title AS "p.title",
COUNT(pc.*) AS "comment_count"
FROM post_comment pc
LEFT JOIN post p ON p.id = pc.post_id
GROUP BY p.id, p.title
ORDER BY p.id
要将上述SQL查询的结果集映射到public class PostTitleWithCommentCount {
private final String postTitle;
private final int commentCount;
public PostTitleWithCommentCount(
String postTitle,
int commentCount) {
this.postTitle = postTitle;
this.commentCount = commentCount;
}
public String getPostTitle() {
return postTitle;
}
public int getCommentCount() {
return commentCount;
}
}
DTO,我们可以使用PostTitleWithCommentCount
批注的classes
属性,如下所示:
@SqlResultSetMapping
@NamedNativeQuery(
name = "PostTitleWithCommentCount",
query = """
SELECT
p.id AS "p.id",
p.title AS "p.title",
COUNT(pc.*) AS "comment_count"
FROM post_comment pc
LEFT JOIN post p ON p.id = pc.post_id
GROUP BY p.id, p.title
ORDER BY p.id
""",
resultSetMapping = "PostTitleWithCommentCountMapping"
)
@SqlResultSetMapping(
name = "PostTitleWithCommentCountMapping",
classes = {
@ConstructorResult(
columns = {
@ColumnResult(name = "p.title"),
@ColumnResult(name = "comment_count", type = int.class)
},
targetClass = PostTitleWithCommentCount.class
)
}
)
注释使我们可以指示Hibernate在实例化DTO对象时使用哪种DTO类以及要调用的构造函数。
请注意,我们使用了ConstructorResult
批注的type
属性来指定将@ColumnResult
强制转换为Java comment_count
。这是必需的,因为某些JDBC驱动程序对SQL聚合函数结果使用int
或Long
。
这是使用JPA调用名为BigInteger
的本机查询的方法:
PostTitleWithCommentCount
而且,我们可以看到返回的List<PostTitleWithCommentCount> postTitleAndCommentCountList = entityManager
.createNamedQuery("PostTitleWithCommentCount")
.setMaxResults(POST_RESULT_COUNT)
.getResultList();
DTO已正确获取:
assertEquals(POST_RESULT_COUNT,postTitleAndCommentCountList.size());
PostTitleWithCommentCount
有关使用JPA和Hibernate获取DTO投影的最佳方法的更多详细信息,请查看this article。
前面的示例显示了如何将SQL聚合结果集映射到DTO。但是,如果我们想返回要为其计数注释的JPA实体怎么办?
要实现此目标,我们可以使用for (int i = 0; i < POST_RESULT_COUNT; i++) {
PostTitleWithCommentCount postTitleWithCommentCount =
postTitleAndCommentCountList.get(i);
assertEquals(
String.format(
"High-Performance Java Persistence - Chapter %d",
i + 1
),
postTitleWithCommentCount.getPostTitle()
);
assertEquals(COMMENT_COUNT, postTitleWithCommentCount.getCommentCount());
}
属性定义要获取的entities
实体,并使用Post
批注的classes
属性映射标量值,在我们的例子中是关联的@SqlResultSetMapping
条记录的数量:
post_comment
在执行@NamedNativeQuery(
name = "PostWithCommentCount",
query = """
SELECT
p.id AS "p.id",
p.title AS "p.title",
p.created_on AS "p.created_on",
COUNT(pc.*) AS "comment_count"
FROM post_comment pc
LEFT JOIN post p ON p.id = pc.post_id
GROUP BY p.id, p.title
ORDER BY p.id
""",
resultSetMapping = "PostWithCommentCountMapping"
)
@SqlResultSetMapping(
name = "PostWithCommentCountMapping",
entities = @EntityResult(
entityClass = Post.class,
fields = {
@FieldResult(name = "id", column = "p.id"),
@FieldResult(name = "createdOn", column = "p.created_on"),
@FieldResult(name = "title", column = "p.title"),
}
),
columns = @ColumnResult(
name = "comment_count",
type = int.class
)
)
命名本机查询时:
PostWithCommentCount
我们将同时获得List<Object[]> postWithCommentCountList = entityManager
.createNamedQuery("PostWithCommentCount")
.setMaxResults(POST_RESULT_COUNT)
.getResultList();
实体和Post
标量列值:
commentCount
答案 8 :(得分:0)
我最近整理了一个快速的概念证明,对我自己和另一位开发人员都非常有效。
使用本机查询并利用SqlResultSetMapping的Spring引导端点,这是代码段。
if(snapshot.hasData){
if (snapshot.data.docs.length != 0) {
return ListView.builder();
} else {
return Text("EMPTY DOCUMENTS");
}
}
添加我的服务
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.metrics.annotation.Timed;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
@RestController
@RequestMapping(value = "/rest/yum-query", produces = APPLICATION_JSON_VALUE)
@Api(tags = {"notification"})
@Timed(extraTags = {"controller", "YumController"})
public class YumController {
private final YumService yumService;
@Autowired
public YumController(YumService yumService) {
this.yumService = yumService;
}
@GetMapping(produces = APPLICATION_JSON_VALUE)
public List<ApprovedApplicationsDTO> findApprovedApplications() {
return yumService.findApprovedApplications();
}
}
为本地查询设置新的查询结果类以映射到
import au.edu.qld.qcaa.sate.serviceaara.domain.repository.YumRepositoryCustom;
import au.edu.qld.qcaa.sate.serviceaara.dto.yum.ApprovedApplicationsDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class YumService {
private YumRepositoryCustom yumRepositoryCustom;
@Autowired
public YumService(YumRepositoryCustom yumRepositoryCustom) {
this.yumRepositoryCustom = yumRepositoryCustom;
}
public List<ApprovedApplicationsDTO> findApprovedApplications() {
return yumRepositoryCustom.findApprovedApplicationsNativeQuery();
}
}
创建新的存储库接口和实现类以从中调用查询
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.ColumnResult;
import javax.persistence.ConstructorResult;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.SqlResultSetMapping;
import java.math.BigInteger;
@MappedSuperclass
@SqlResultSetMapping(name = "ApprovedApplicationQueryResultBean",
classes = {
@ConstructorResult(
targetClass = ApprovedApplicationQueryResultBean.class,
columns = {
@ColumnResult(name = "application_id", type = BigInteger.class),
@ColumnResult(name = "application_type", type = String.class),
@ColumnResult(name = "assessment_identifier", type = String.class),
@ColumnResult(name = "aara_code", type = String.class),
@ColumnResult(name = "aara_code_child", type = String.class),
@ColumnResult(name = "completion_year", type = Integer.class),
@ColumnResult(name = "reason", type = String.class),
@ColumnResult(name = "code", type = String.class),
@ColumnResult(name = "long_description", type = String.class),
@ColumnResult(name = "identified_condition", type = String.class),
@ColumnResult(name = "other", type = String.class),
@ColumnResult(name = "decision_code", type = String.class),
}
)
})
@NoArgsConstructor
@AllArgsConstructor
@Data
public class ApprovedApplicationQueryResultBean {
@Id
private BigInteger applicationId;
private String applicationType;
private String assessmentIdentifier;
private String aaraCode;
private String aaraCodeChild;
private Integer completionYear;
private String reason;
private String code;
private String longDescription;
private String identifiedCondition;
private String other;
private String decisionCode;
}
添加我的端点响应DTO
import au.edu.qld.qcaa.sate.serviceaara.dto.yum.ApprovedApplicationsDTO;
import java.util.List;
public interface YumRepositoryCustom {
List<ApprovedApplicationsDTO> findApprovedApplicationsNativeQuery();
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
@Slf4j
public class YumRepositoryCustomImpl implements YumRepositoryCustom {
@PersistenceContext
private EntityManager em;
@Override
public List<ApprovedApplicationsDTO> findApprovedApplicationsNativeQuery() {
StringBuilder q = new StringBuilder();
q.append("select distinct a4.application_id, a4.application_type, a3.assessment_identifier, ");
q.append("a3.aara_code, ad.aara_code_child, a3.completion_year, c.reason, rd.code, rd.long_description, ic.identified_condition, ic.other, ad2.decision_code ");
q.append("from category c ");
q.append("left join application a4 on a4.application_id = c.application_id ");
q.append("left join arrangement a3 on a3.application_id = a4.application_id ");
q.append("left join arrangement_detail ad on a3.arrangement_id = ad.arrangement_id ");
q.append("left join identified_condition ic on ic.category_id = c.category_id ");
q.append("left join reference_data rd on rd.code = c.reason ");
q.append("left join arrangement_decision ad2 on ad2.arrangement_id = a3.arrangement_id ");
q.append("left JOIN (SELECT max(ad3.arrangement_decision_id) as theid ");
q.append("FROM arrangement_decision ad3 ");
q.append("GROUP BY ad3.arrangement_id) b on ad2.arrangement_decision_id = b.theid ");
q.append("where a4.application_type = ?1 and a3.completion_year = ?2 ");
q.append("and a4.is_active = true and a3.is_active = true and ic.is_active = true and c.is_active = true ");
q.append("order by 1 ");
Query query = em.createNativeQuery(q.toString(), "ApprovedApplicationQueryResultBean");
query.setParameter(1, ApplicationConstants.APPLICATION_TYPE_AARA);
query.setParameter(2, Calendar.getInstance().get(Calendar.YEAR));
List<ApprovedApplicationQueryResultBean> entityResults = query.getResultList();
return entityResults.stream().map(entity -> {
return mapToDTO(entity);
}).collect(Collectors.toList());
}
private ApprovedApplicationsDTO mapToDTO(ApprovedApplicationQueryResultBean entity) {
return ApprovedApplicationsDTO.builder()
.applicationId(entity.getApplicationId())
.applicationType(entity.getApplicationType())
.aaraCode(entity.getAaraCode())
.aaraCodeChild(entity.getAaraCodeChild())
.completionYear(entity.getCompletionYear())
.reason(entity.getReason())
.code(entity.getCode())
.longDescription(entity.getLongDescription())
.identifiedCondition(entity.getIdentifiedCondition())
.other(entity.getOther())
.decisionCode(entity.getDecisionCode())
.build();
}
}
import lombok.Builder;
import lombok.Data;
import java.math.BigInteger;
@Data
@Builder
public class ApprovedApplicationsDTO {
private BigInteger applicationId;
private String applicationType;
private String assessmentIdentifier;
private String aaraCode;
private String aaraCodeChild;
private Integer completionYear;
private String reason;
private String code;
private String longDescription;
private String identifiedCondition;
private String other;
private String decisionCode;
}
答案 9 :(得分:-1)
此解决方案独立于JPA实施。一旦您将本机查询的结果收集为
List<Object[]> = em.createNativeQueryBar(QUERY, "foo").getResultList();
,如果您需要将每个List元素映射到一个Person,例如
Class Person { String name; Int age; }
其中列表元素[0]是名称,元素[1]是年龄。
您可以使用ObjectMapper将Object []转换为Person。您需要在类上添加@JsonFormat批注。
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
Class Person { String name; Int age; }
并将Object []转换为Person作为
ObjectMapper mapper = new ObjectMapper();
JSONArray jsonArray = new JSONArray(Arrays.asList(attributes)).toString();
Person person = mapper.readValue(jsonArray, Person.class);
答案 10 :(得分:-1)
@MappedSuperclass
@SqlResultSetMapping(name="foo",
classes = {
@ConstructorResult(
targetClass = Bar.class,
columns = {
@ColumnResult(name = "barId", type = Long.class),
@ColumnResult(name = "barName", type = String.class),
@ColumnResult(name = "barTotal", type = Long.class)
})
})
您可以这样做,但是由于它不太舒适,因此不建议这样做。您可以按照以下步骤进行操作。
Query query = em.createNativeQueryBar(QUERY);
... set some parameters ...
List<Object[]> result = query.getResultList();
List<Bar> list = result.stream().map(
objects -> {
Bar bar = new Bar();
bar.setBarId(Long.parseLong(objects[0].toString()));
bar.setBarName(objects[1].toString());
bar.setBarTotal(Long.parseLong(objects[2].toString()));
...
return bar;
}
).collect(Collectors.toList());