Foreach imbriquée dans MyBatis 3 pour une HashMap paramètre
Je suis en train d'essayer de trouver une solution pour le problème suivant à l'aide de MyBatis 3.0.6:
J'ai besoin de construire une dynamique de sélectionner déclaration fondée sur une série de paramètres, dont l'un est de type HashMap<String, List<String>>
. Le défi est de comprendre comment faire de MyBatis itérer sur toutes les touches à l'extérieur de foreach boucle ainsi que d'itérer sur les éléments de la liste de valeur dans la boucle interne.
Pour illustrer, supposons que mon hash map paramètre appelé filtre contient les états (liste des codes d'état, chaque liste étant la valeur) par pays (country code de la clé), comme suit:
'US' -> {'CO','NY','MI','AZ'};
'CA' -> {'ON','BC','QC'}
J'ai besoin de mon code SQL dynamique pour ressembler à ceci (dans une grave forme simplifiée):
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')
J'imagine mon mappeur XML devrait ressembler à quelque chose comme ceci:
<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>
La question est donc, quelle est la bonne syntaxe pour obtenir le pays.les états à parcourir dans le imbriqués foreach boucle?
Mise à JOUR
Après quelques retouches, je ne pouvais pas obtenir MyBatis à jouer très bien avec la table de hachage basée sur l'approche, j'ai donc fini par l'ajout d'une nouvelle classe qui associe plusieurs valeurs à leur valeur parent, puis en passant une liste de ces objets MyBatis. À l'aide de l'un des pays/états de l'exemple ci-dessus, la classe ressemble à ceci:
public class Filter {
private String country;
private ArrayList<String> states;
//... public get accessors here ...
}
La méthode DAO:
public void QueryResult[] getResults( @Param("criteria") List<Filter> criteria) ...
Et la MyBatis cartographie:
<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>
Fonctionne comme un charme.
OriginalL'auteur Caspian Canuck | 2012-09-10
Vous devez vous connecter pour publier un commentaire.
En fait, vous pouvez utiliser la valeur de pays pour le rechercher dans le filtre de la carte et de le faire fonctionner comme vous l'avait initialement. Dans la seconde boucle, votre collection sera défini comme
filter.get(country)
et ça devrait être bon. C'est bien sûr, étant donné que je suis l'interprétation de votre question correctement.OriginalL'auteur user1738084
J'avais quelque chose à être insérée que d'une carte où chaque carte de clé de cartes à une liste.
J'ai écrit la requête de cette façon.
OriginalL'auteur tariq zafar
Maintenant, je peux le faire.
OriginalL'auteur Jin Kwon