我有一个从非常复杂的查询返回的结果集,我更喜欢使用SQL而不是HQL运行。
仅供上下文使用 - 它是建议结果集,建议将客户支付的现有对象替换为可能成本更低的其他类型的对象。因此,对于每个产品的每个建议,有3列重复自己 - id
,type
,price
和2个代表建议的不同列 - new_type
和{{1} }。
我的结果集看起来像这样:
new_price
我想将它映射到看起来像这样的
的Java对象id type price new_type new_price
------------------------------------------------------
1 14 90 12 85
1 14 90 11 87
1 14 90 7 73
2 9 80 7 73
2 9 80 4 52
我不确定Hibernate是否提供开箱即用的这种变压器(找不到)。我也不确定是否可以编写新的变压器。
答案 0 :(得分:0)
这是我在此期间使用的解决方案,我不会接受答案,希望有更好的答案:
public class SuggestionsTransformer implements ResultTransformer {
Map<String, Suggestions> suggestionsMap = new HashMap<>();
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
String id = (String) tuple[0];
String origType = (String) tuple [1];
float origPrice = (float) tuple[2];
String suggestedType = (String) tuple[3];
float suggestedPrice = (float) (tuple[4] == null ? 0.0f : tuple[4]);
Suggestions suggestions;
if(suggestionsMap.containsKey(id)) {
suggestions = suggestionsMap.get(id);
} else {
suggestions = new Suggestions();
suggestions.setId(id);
suggestions.setOrigType(origType);
suggestions.setOrigPrice(origPrice);
}
suggestions.addSavingSuggestion(suggestedType, suggestedPrice);
return suggestions;
}
@Override
public List transformList(final List list) {
// This method makes sure that each id returns only once
Set resultWithoutDuplications = new HashSet(list);
return new ArrayList(resultWithoutDuplications);
}
}
在我的DAO中(我正在使用实体经理):
Query query = entityManager.createNativeQuery("Some native SQL query here");
SQLQuery sqlQuery = query.unwrap(SQLQuery.class); // Query interface does not have setResultTransformer so instead you can unwrap and get the underlying instance of the sql query
sqlQuery.setResultTransformer(new UnderutilizedSuggestionsTransformer());
return new ArrayList<>(sqlQuery.list());