从数据库中获取有序映射的值

时间:2015-12-30 09:26:09

标签: java mysql hibernate jdbc collections

我正在处理业务需求,我需要在订单中获取两个字段值作为键/值对。我正在使用mysql和hibernate来做db操作。

我的表包含三个colomns(fieldId,FieldName,FieldType),其中fieldId为主键。我的要求是将fieldIds和FieldNames值作为基于fieldType的有序映射获取。

这是我的样本表数据。

FieldId  FieldName  Type
1        f1         x
2        f2         x
3        f3         x
4        f4         y

我希望将所有fieldIds和fieldNames作为特定字段类型的升序器(基于fieldId)中的键值对说“x”。请帮帮我。

1 个答案:

答案 0 :(得分:0)

我的假设是你有一个与你提供的字段配置相关的Hibernate实体:

@Entity
@Table
public class FieldEntity {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "FieldId")
  private Long fieldId;
  @Column(name = "FieldName")
  private String fieldName;
  @Column(name = "Type")
  private String type;
}

第一步是根据您的要求(按类型)自行获取实际数据行。您可以选择让数据库为您执行排序,也可以在java代码中自行执行。这取决于您的查询的重用。我会告诉你们两个。

按查询排序

首先,将以下注释添加到FieldEntity下面的@Table课程中。

@NamedQuery(
  name = "FieldEntity.findByType", 
  query = "FROM FieldEntity e WHERE e.type = :type ORDER BY e.fieldId")

命名查询是一项很棒的功能,因为它们通常在启动时由ORM提供程序解析,通知您任何查询错误,并且还可以降低运行时成本,因为它们已经过预解析。

下一步是使用这个NamedQuery来从hibernate获取结果。

// construct a hibernate query using named query, specifying the type parameter.
Query query = session.getNamedQuery("FieldEntity.findByType").setString("type", type);

// Now iterate and capture results
List<FieldEntity> results = new ArrayList<>();
for(Object[] row : query.list()) {
  FieldEntity e = row.get(0);
  results.add(e);
}

获得查询结果后(已经按FieldId排序),它是一个简单的迭代循环,并根据您的业务需求将它们添加到地图中。这种逻辑通常是我在业务用例类中看到的。

public Map<Long, String> getFieldEntityMapByType(String type) {
  List<FieldEntity> results = // call DAO and get list.
  Map<Long, String> map = new LinkedHashMap<>();
  for(FieldEntity entity : results) 
    map.put(entity.getFieldId(), entity.getFieldName());
  return map;
}

由于结果已经排序,因此我在迭代结果集时使用LinkedHashMap来保留插入顺序。

无查询排序

在这种情况下,您的@NamedQuery不会包含 ORDER BY 子句,而是使用SortedMap而不是LinkedHashMap,代码仍然存在相同。

SortedMap确保根据字段ID的自然排序顺序对条目进行排序,因为它们已添加到地图中。

<强>结论

后一种方法的好处是您可以通过用例更改排序行为而不会影响数据库访问代码,但是成本影响是排序正在应用程序服务器的内存中完成。根据所讨论的实体数量,对于大型结果集,这可能会出现问题。

前一种方法适用于较大的结果集,并且可以通过使用基于标准的查询而不是命名查询来优化,以便在运行时更改排序顺序,只需以查询解析每次执行为代价。