28

我想使用 spring mvc @modelAttribute 在我的 Jsp 页面中显示类别列表。

在我的 mapper.xml 文件中是

<select id="selectAllCategories" resultMap="BaseResultMap">
  select id, name from categories  
</select>

在我的 Mapper.java 类中,我有方法

List<Map<String, String>> selectAllCategories();

我想要一个这样的方法:

Map<Integer, String>`selectAllCategories();

而不是List<Map<>>,这可能吗?

4

1 回答 1

47

你想得到一个Map<Integer,String>Integer 是 theid和 String 是 the 的地方name。如果您的表中有 200 个类别,您会希望地图中有 200 个条目,而不是 200 个地图的列表。

MyBatis 不能开箱即用地做到这一点,但你可以使用它的工具来做到这一点。我看到两个选项。

选项1:

第一个不是你要求的,但值得展示。它为您提供了一个Map<Integer,Category>where Category 是具有 id、name(以及可能来自 categories 表的其他字段)的类别表的域对象。@MapKey创建 Category 域对象后,在 MyBatis 中使用注释很容易做到这一点:

@Select("SELECT id, name FROM categories")
@MapKey("id")
Map<Integer,Category> getAllCategories();

在您的代码中,您将执行以下操作:

MyMapper mapper = session.getMapper(MyMapper.class);
Map<Integer,Category> m = mapper.getAllCategories();

根据您是否可以将名称提取为 Category 对象的属性,这可能适用于您的用例,也可能不适用。


选项 2:

为了得到Map<Integer,String>你想要的,我知道的最简单的方法是创建一个实现 MyBatis ResultHandler接口的类。

您的 ResultHandler 将使用 MyBatis 创建的 column-name => column-value 的默认 hashmap 并创建单个主 Map。这是代码:

public class CategoryResultHandler implements ResultHandler {

  Map<Integer,String> inMap = new HashMap<Integer,String>(); 

  public Map<Integer, String> getIdNameMap() {
    return inMap;
  }

  @Override
  public void handleResult(ResultContext rc) {
    @SuppressWarnings("unchecked")
    Map<String,Object> m = (Map<String,Object>)rc.getResultObject();
    inMap.put((Integer)getFromMap(m, "id"), 
              (String)getFromMap(m, "name"));
  }

  // see note at bottom of answer as to why I include this method
  private Object getFromMap(Map<String, Object> map, String key) {
    if (map.containsKey(key.toLowerCase())) {
      return map.get(key.toLowerCase());
    } else {
      return map.get(key.toUpperCase());
    }
  }
}

handleResult 方法在类别表中的每行调用一次。你告诉 MyBatis 使用 ResultHandler,然后像这样提取你的主地图:

CategoryResultHandler rh = new CategoryResultHandler();
session.select("getAllCategories", rh);
Map<Integer,String> m = rh.getIdNameMap();

这两个中的一个应该适合你。

最后的几点说明:

  1. 为什么我要包含getFromMap()辅助方法?因为你不能总是控制 MyBatis 返回的 hashmap 中列名的大小写。更多细节在这里:mybatis- 3.1.1。如何覆盖mybatis返回的resultmap

  2. 我在 mybatis-koans 的 Koan26 中有这些解决方案的工作示例(我根据您的问题添加): https ://github.com/midpeter444/mybatis-koans

于 2012-08-11T13:33:45.770 回答