2012-09-10 6 views
5

ためMyBatisの3でネストされたforeachの私はMyBatisの3.0.6を使用して、次の問題への解決策を把握しようとしていますにそのタイプはHashMap<String, List<String>>です。課題は、外側のforeachループ内のすべてのキーに対してMyBatisを反復させる方法と、内側のループの値リストの要素を反復する方法を理解することです。HashMapのパラメータ

'US' -> {'CO','NY','MI','AZ'}; 
'CA' -> {'ON','BC','QC'} 
:そうのような国(キーとして国コード)ごとに、説明私のハッシュマップのパラメータは、 フィルタは、状態(状態コードのリスト、値である各リスト)が含まれて呼ばれると仮定する

私は、動的SQL(肉眼的に簡略化した形で)このように見える必要があります。

SELECT * 
FROM Table1 
WHERE ... some static criteria goes here... 
     AND RowId IN (SELECT RowId FROM Table2 WHERE Country = 'US' AND State IN ('CO','NY','MI','AZ') 
     AND RowId IN (SELECT RowId FROM Table2 WHERE Country = 'CA' AND State IN ('ON','BC,'QC') 

私はこのようになります私のマッパーXMLを想像:

<select id="getData" resultType="QueryResult"> 
SELECT * 
FROM Table1 
WHERE ... some static criteria goes here... 
    <if test="filter != null"> 
     <foreach item="country" index="i" collection="filter" separator="AND"> 
      RowId IN (SELECT RowId 
         FROM Table2 
         WHERE Country = #{country} AND State IN 
      <foreach item="state" index="j" collection="country.states" separator="," open="(" close=")"> 
       #{state} 
      </foreach> 
     </foreach> 
    </if> 
</select> 

そこで問題は、ネストされたのforeachループで反復処理するcountry.statesを取得するための適切な構文は何ですか?


UPDATE

いくつかの工夫の後、私はMyBatisのは、HashMapのベースのアプローチでうまくプレーすることができなかったので、私は彼らの親の値に複数の値をマップする新しいクラスを追加することになりました、そのようなオブジェクトのリストをMyBatisに渡します。上記の国/州の例を使用して、クラスがそうのようになります。

public class Filter { 
    private String country; 
    private ArrayList<String> states; 

    // ... public get accessors here ... 
} 

DAO方法:

public void QueryResult[] getResults(@Param("criteria") List<Filter> criteria) ... 

そして、MyBatisのマッピング:魔法のように

<select id="getData" resultType="QueryResult"> 
SELECT * 
FROM Table1 
WHERE ... some static criteria goes here... 
    <if test="criteria!= null"> 
     <foreach item="filter" index="i" collection="criteria" separator="AND" open="AND"> 
      RowId IN (SELECT RowId 
         FROM Table2 
         WHERE Country = #{filter.country} AND State IN 
      <foreach item="state" index="j" collection="filter.states" separator="," open="(" close=")"> 
       #{state} 
      </foreach> 
     </foreach> 
    </if> 
</select> 

作品。

答えて

3

実際には、国の値を使用してフィルタマップ内を検索し、最初に持っていたとおりに動作させることができます。 2番目のループでは、コレクションはfilter.get(country)と定義されています。これは私があなたの質問を正しく解釈していることを考慮したものです。

1

マップとして挿入するものがありました。各マップキーがリストにマップされています。 私はこのようにクエリを書いた。

INSERT INTO TB_TEST (group_id, student_id) VALUES 
<foreach collection="idMap.entrySet()" item="element" index="index" separator=","> 
     <foreach collection="element.value" item="item" separator="," > 
      (#{element.key} #{item})  
     </foreach> 
    </foreach> 
+0

私のためにそれを固定した。ありがとう! – 98percentmonkey

0

今のところ私はこれを行うことができます。

<foreach collection="myMap" index="key" item="value"> 
    <foreach collection="value" item="element"> 
    ... = #{key} ... 
    ... = #{element}) 
    </foreach> 
</foreach>