Подтвердить что ты не робот

Верните HashMap в mybatis и используйте его как ModelAttribute в spring MVC

Я хочу отобразить список категорий на моей странице Jsp с помощью spring mvc @modelAttribute.

В моем файле 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<>>, возможно ли это?

4b9b3361

Ответ 1

Вы хотите получить Map<Integer,String>, где Integer - это id, а String - name. Если в вашей таблице было 200 категорий, вам понадобилось бы 200 записей на вашей карте, а не список из 200 карт.

MyBatis не может это сделать из коробки, но вы можете использовать его возможности для этого. Я вижу два варианта.

Вариант 1:

Во-первых, это не совсем то, о чем вы просили, но стоит показать. Он дает вам Map<Integer,Category>, где Category является объектом домена для таблицы категорий, которая имеет идентификатор, имя (и, возможно, другие поля из таблицы категорий). После того, как вы создали объект домена категории, это довольно легко сделать в MyBatis, используя аннотацию @MapKey:

@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 будет использоваться hashmap по умолчанию column-name = > column-value, который MyBatis создает и создает одну основную карту. Здесь код:

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();

Один из этих двух должен работать на вас.

Несколько заключительных заметок: