我有一个相当复杂的查询(HQL或Criteria查询的嵌套级别太多),因此我将其编写为SQLQuery。我真的很想使用AliasToBeanResultTransformer将我的结果转换为List,但是我遇到了一些问题。我在下面介绍了一些代码片段。
当我记录转换查询的结果时,我可以看到转换器确实创建了一个列表,但是,每个AdvancedClauseSearchResultDTO中的所有字段均为空。我认为这意味着我在别名方面做错了... AliasToBeanResultTransformer无法找到要调用的正确的setter。但是,AdvancedClauseSearchResultDTO类确实为我在sql字符串中别名的每个列都有公共设置器。如果这是一个Criteria查询,我将使用投影为每个要返回的列定义一个别名,但是我不确定如何使用SQLQuery完成同一件事。
关于如何获取别名的任何建议,以便ResultTransformer可以使用它们?我看过一些有限的文档,建议使用'as aliasName'方法应该可以,但似乎不适合我。
查询字符串定义的开始摘要,请注意别名“as”的定义
StringBuffer clauseBaseQuery = new StringBuffer();
clauseBaseQuery.append("select ");
clauseBaseQuery.append(" clauseDetail.clause_detail_id as clauseDetailId,");
clauseBaseQuery.append(" clauseDetail.clause_id as clauseId,");
clauseBaseQuery.append(" providers.provider_name as provider, ");
clauseBaseQuery.append(" products.product_name as product, ");
SQLQuery创建和设置resultTransformer
Query query = session.createSQLQuery(clauseBaseQuery.toString());
query.setResultTransformer(new AdvancedClauseSearchResultTransformer());
return (List<AdvancedClauseSearchResultDTO>)query.list();
AdvancedClauseSearchResultTransformer类(使用AliasToBeanResultTransformer,然后进行一些额外的处理):
class AdvancedClauseSearchResultTransformer implements ResultTransformer {
//Use the aliasTransformer to do most of the work
ResultTransformer aliasTransformer = Transformers.aliasToBean(AdvancedClauseSearchResultDTO.class);
@Override
public List transformList(List list) {
log.debug("transforming CLAUSE results");
List<AdvancedClauseSearchResultDTO> result = aliasTransformer.transformList(list);
//for each row, set the status field
for (AdvancedClauseSearchResultDTO dto : result) {
log.debug("dto = " + dto);
String status = null;
Date effectiveDate = dto.getEffectiveDate();
Date terminationDate = dto.getTerminationDate();
Date now = new Date(System.currentTimeMillis());
if (now.before(effectiveDate)) {
status = "Pending";
} else if (now.after(terminationDate)) {
status = "Terminated";
} else {
status = "Active";
}
dto.setStatus(status);
if (StringUtils.isNotEmpty(dto.getReasonForAmendment())){
dto.setAmended(Boolean.TRUE);
}else{
dto.setAmended(Boolean.FALSE);
}
}
return result;
}
@Override
public Object transformTuple(Object[] os, String[] strings) {
Object result = aliasTransformer.transformTuple(os, strings);
return result;
}
}
最佳答案
这取决于您使用的后端,在您的帖子中没有提到。
除非您正确地对进行转义,否则各种数据库后端对列都使用不区分大小写的命名方式,因此即使您使用适当的大小写指定了列结果名称,它们也最终以CLAUSEDETAILID
或clausedetailid
的形式被检索。
使用PostgreSQL(我也相信Oracle),您必须像这样编写查询(注意引号):StringBuffer clauseBaseQuery = new StringBuffer();
clauseBaseQuery.append("select ");
clauseBaseQuery.append(" clauseDetail.clause_detail_id as \"clauseDetailId\",");
clauseBaseQuery.append(" clauseDetail.clause_id as \"clauseId\",");
clauseBaseQuery.append(" providers.provider_name as \"provider\", ");
clauseBaseQuery.append(" products.product_name as \"product\", ");
Query query = session.createSQLQuery(clauseBaseQuery.toString());
这样,只要您还指定了转换,Hibernate就能正确识别该属性并将结果映射到Bean:query.setResultTransformer(Transformers.aliasToBean(AdvancedClauseSearchResultDTO.class));
如@ zinan.yumak所建议。