在mybatis中返回HashMap并将其用作spring MVC中的ModelAttribute

use*_*884 24 java ibatis spring-mvc mybatis

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

在我的mapper.xml文件中

<select id="selectAllCategories" resultMap="BaseResultMap">
  select id, name from categories  
</select>
Run Code Online (Sandbox Code Playgroud)

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

List<Map<String, String>> selectAllCategories();
Run Code Online (Sandbox Code Playgroud)

我想要一个像这样的方法:

Map<Integer, String>`selectAllCategories();
Run Code Online (Sandbox Code Playgroud)

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

quu*_*x00 38

你想得到一个Map<Integer,String>Integer所在的位置,id而String就是name.如果表中有200个类别,则表示地图中有200个条目,而不是200个地图的列表.

MyBatis不能完全开箱即用,但您可以使用它的设施来做到这一点.我看到两个选择.

选项1:

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

@Select("SELECT id, name FROM categories")
@MapKey("id")
Map<Integer,Category> getAllCategories();
Run Code Online (Sandbox Code Playgroud)

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

MyMapper mapper = session.getMapper(MyMapper.class);
Map<Integer,Category> m = mapper.getAllCategories();
Run Code Online (Sandbox Code Playgroud)

根据您是否可以将名称提取为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());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

handleResult方法在类别表中每行调用一次.您告诉MyBatis使用ResultHandler然后提取您的主映射,如下所示:

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

其中一个应该适合你.

最后几点说明:

  1. 为什么我要包含getFromMap()辅助方法?因为您无法始终控制MyBatis返回的散列映射中列名称的大小写.更多细节:mybatis- 3.1.1.如何覆盖从mybatis返回的resultmap

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