web-dev-qa-db-ja.com

mybatisでHashMapを返し、spring MVCでModelAttributeとして使用します

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<>>、それは可能ですか?

21
user965884

整数がidで、文字列がnameである_Map<Integer,String>_を取得したい場合。テーブルに200個のカテゴリがある場合、200個のマップのリストではなく、200個のエントリがマップに必要です。

MyBatisはすぐにそれを行うことはできませんが、その機能を使用してそれを行うことができます。 2つのオプションがあります。

オプション1:

最初のものは、あなたが求めたものとはまったく異なりますが、示す価値があります。これは_Map<Integer,Category>_を提供します。ここで、Categoryはid、name(および場合によってはcategoryテーブルのその他のフィールド)を持つカテゴリテーブルのドメインオブジェクトです。 Categoryドメインオブジェクトを作成した後、これは_@MapKey_アノテーションを使用して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のデフォルトのハッシュマップを使用します。コードは次のとおりです。

_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メソッドは、カテゴリテーブルの行ごとに1回呼び出されます。 MyBatisにResultHandlerを使用してから、次のようにマスターマップを抽出するように指示します。

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

これらの2つのうちの1つが動作するはずです。

最後の注意事項:

  1. なぜgetFromMap()ヘルパーメソッドを含めたのですか? MyBatisが返すハッシュマップの列名の大文字小文字を常に制御できるわけではないためです。詳細はこちら: mybatis- 3.1.1。mybatisから返された結果マップをオーバーライドする方法

  2. Mybatis-koansのKoan26にこれらのソリューションの実例があります(あなたの質問に基づいて追加しました): https://github.com/midpeter444/mybatis-koans

37
quux00