1

我有一个从一个非常复杂的查询返回的结果集,我更喜欢使用 SQL 而不是 HQL 运行它。仅用于上下文 - 这是一个建议结果集,建议将客户支付的现有对象替换为成本可能更低的另一种类型的对象。因此,对于每个产品的每个建议,都有 3 个重复的列 - idtypeprice2 个代表建议的不同列 -new_typenew_price

我的结果集如下所示:

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 

我想将它映射到一个看起来像这样的 Java 对象

class Suggestion {
  private Long id;
  private Integer type;
  private float price;

  private List<Replacement> replacements;

  private class Replacement {
     private Integer type;
     private float price;

     // getters, setters, constructors removed
  }

     // getters, setters, constructors removed
}

我不确定 Hibernate 是否提供这种开箱即用的变压器(找不到)。我也不确定写一个新的变压器是要走的路。

4

1 回答 1

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());
于 2016-03-07T14:12:00.803 回答