próbuję wymyślić rozwiązanie następującego problemu z wykorzystaniem MyBatis 3.0.6:Zagnieżdżone foreach w MyBatis 3 dla parametru HashMap
muszę zbudować dynamiczny SELECT na podstawie szeregu parametrów, jeden z tego jest typu HashMap<String, List<String>>
. Wyzwaniem jest dowiedzieć się, jak zrobić MyBatis iteracyjne nad wszystkimi kluczami w zewnętrznej pętli foreach, jak również iterować nad elementami listy wartości w wewnętrznej pętli.
Aby zilustrować, załóżmy, że mój hash mapa parametr zwany filtr zawiera Zjednoczone (wykazy kodów państwowych, każda lista jest wartością) od kraju (kod kraju jako klucz) tak:
'US' -> {'CO','NY','MI','AZ'};
'CA' -> {'ON','BC','QC'}
muszę mój dynamiczny SQL, aby wyglądać następująco (w rażąco uproszczonej formie):
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')
bym sobie wyobrazić moje odwzorowujący XML powinien wyglądać mniej więcej tak:
<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>
Więc pytanie brzmi, jaka jest właściwa składnia uzyskać country.states do iteracyjnego w zagnieżdżonej foreach pętli?
UPDATE
Po pewnym majsterkowania nie mogłem dostać MyBatis grać ładnie z podejściem HashMap oparte, więc skończyło się na dodanie nowej klasy, która mapuje wiele wartości do wartości nadrzędnej, następnie przekazanie listy takich obiektów do MyBatis. Na przykładzie krajach/stanach powyżej, klasa wygląda tak:
public class Filter {
private String country;
private ArrayList<String> states;
// ... public get accessors here ...
}
Metoda DAO:
public void QueryResult[] getResults(@Param("criteria") List<Filter> criteria) ...
I odwzorowanie 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>
działa jak czar.
THIS! naprawił to dla mnie. Dzięki! – 98percentmonkey