Comment utiliser les Annotations avec iBatis (myBatis) pour une requête?
Nous aimerions utiliser uniquement les annotations avec MyBatis; nous essayons vraiment d'éviter xml. Nous essayons d'utiliser un "À la" clause:
@Select("SELECT * FROM blog WHERE id IN (#{ids})")
List<Blog> selectBlogs(int[] ids);
MyBatis ne semble pas en mesure de choisir le tableau d'entiers et de les mettre dans la requête. Il semble "tomber doucement" et nous n'obtenez pas de résultats.
Il semble que nous pourrions faire à l'aide des mappages XML, mais nous aimerions vraiment à éviter. Est-il correct d'annotation syntaxe de cette?
- Normal SQL nécessite SQL dynamique pour utiliser une variable qui représente une liste séparée par des virgules de valeurs.
- Poneys: Mes excuses, je ne suis pas sûr de ce que vous essayez de dire? Si je devais prendre votre sagesse et de l'appliquer à ce problème, ce serait ma solution ressembler en particulier?
- Je n'ai jamais travaillé avec iBatis, mais pouvez-vous créer une instruction SQL comme une chaîne de caractères (y compris le contenu de variable) avant toute chose se passe? C'est tout le SQL dynamique est vraiment...
Vous devez vous connecter pour publier un commentaire.
Je crois que c'est une nuance de jdbc de déclarations préparées à l'avance et de ne pas MyBatis. Il y a un lien ici qui explique ce problème et propose différentes solutions. Malheureusement, aucune de ces solutions sont viables pour votre application, cependant, il est toujours une bonne lecture pour comprendre les limites des déclarations préparées à l'avance en ce qui concerne une "DANS" la clause. Une solution (peut-être sous-optimale) peuvent être trouvés sur le DB-spécifique côté des choses. Par exemple, dans postgresql, on peut utiliser:
"TOUT" est le même que le "EN" et "::int[]" est le type coulée de l'argument dans un tableau d'entiers. L'argument qui est injecté dans la déclaration devrait ressembler à quelque chose comme:
Je crois que la réponse est la même que celle qui est accordée dans cette question. Vous pouvez utiliser myBatis SQL Dynamique dans vos annotations en procédant comme suit:
La
<script>
élément permet de SQL dynamique d'analyse et d'exécution pour l'annotation. Il doit être très d'abord le contenu de la chaîne de requête. Rien ne doit être en face de lui, pas même un espace blanc.Noter que les variables que vous pouvez utiliser dans les différentes XML, les balises de script suivent les mêmes conventions de nommage que régulièrement des requêtes, donc si vous voulez faire référence à vos arguments de méthode en utilisant des noms autres que "param1", "param2", etc... vous avez besoin de faire précéder chaque argument avec un @Param annotation.
<
de la<script>
tag, ou vous aurez toutes sortes d'étranges erreurs.Avait quelques recherches sur ce sujet.
@Select("<script>...</script>")
. Toutefois, l'écriture xml en java annotation est assez disgracieux. pensez à ce@Select("<script>select name from sometable where id in <foreach collection=\"items\" item=\"item\" seperator=\",\" open=\"(\" close=\")\">${item}</script>")
@SelectProvider
fonctionne très bien. Mais c'est un peu compliqué à lire.pstm.setString(index, "1,2,3,4")
permettra à votre SQL comme ceciselect name from sometable where id in ('1,2,3,4')
. Mysql va convertir les caractères'1,2,3,4'
nombre1
.Regarder dans mybatis sql dynamique mécanisme, il a été mis en œuvre par
SqlNode.apply(DynamicContext)
. Toutefois, la fonction @Select sans<script></script>
annotation ne va pas passer le paramètre viaDynamicContext
voir aussi
org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
org.apache.ibatis.scripting.xmltags.DynamicSqlSource
org.apache.ibatis.scripting.xmltags.RawSqlSource
Donc,
DynamicSqlSource
. Cependant, vous avez encore à écrire\"
partout.Mon projet de prendre la solution 3 et voici le code:
Et l'utilisation:
J'ai fait un petit truc dans mon code.
Et j'ai utilisé ce MyHandler dans SqlMapper :
Il travaille maintenant 🙂
J'espère que cela aidera quelqu'un.
Evgeny
where id_parent in ('1,2,3')
avec 1 paramètre au lieu dewhere id_parent in (1,2,3)
avec 3 paramètres. C'est pire si vous utilisez des chaînes car cela permettrait de créerwhere name in ('''Tom'',''Dick'',''Harry''')
avec 1 paramètre et les guillemets échappés avec le doublage.Autre option peut être
Dans mon projet, nous sommes déjà à l'aide de Google, de Goyave, de sorte qu'un raccourci rapide est.
where id_parent in ('1,2,3')
avec 1 paramètre au lieu dewhere id_parent in (1,2,3)
avec 3 paramètres. C'est pire si vous utilisez des chaînes car cela permettrait de créerwhere name in ('''Tom'',''Dick'',''Harry''')
avec 1 paramètre et les guillemets échappés avec le doublage.Dans Oracle, j'utilise une variante de Tom Kyte du générateur de jetons pour gérer liste inconnue tailles (donnée Oracle 1k limite DANS la clause et l'aggravation de faire plusieurs INs pour la contourner). C'est pour varchar2, mais elle peut être adaptée pour les nombres (ou vous pouvez simplement compter sur Oracle en sachant que '1' = 1 /frisson).
En supposant que vous transmettez ou effectuer myBatis incantations pour obtenir
ids
comme une Chaîne de caractères à utiliser:Le code:
Vous pouvez utiliser un type personnalisé gestionnaire pour ce faire. Par exemple:
Enregistrer le type de gestionnaire dans votre MyBatis config (ou préciser dans votre annotation):
Vous pouvez ensuite les utiliser comme ceci
Toutefois, cela ne pas travail pour MySQL, parce que le connecteur MySQL ne prend pas en charge
setArray()
pour les instructions préparées.Une solution possible pour MySQL est d'utiliser
FIND_IN_SET
au lieu deIN
:Et votre type de gestionnaire devient:
Note: je ne connais pas les performances de
FIND_IN_SET
, afin de tester s'il est important