Puis-je passer d'une Liste en tant que paramètre à une MyBatis mappeur?
Je suis en train de définir un simple @Select
annotation dans MyBatis d'obtenir une collection d'objets sur la base des critères définis par une clause IN. Le SQL ressemble à quelque chose comme:
SELECT * FROM employees WHERE employeeID IN (1, 2, 3);
La liste est générée dynamiquement, donc je ne sais pas combien de paramètres qu'il aura. Je voudrais juste passer un List
de valeurs, quelque chose comme:
@Select("SELECT * FROM employees WHERE employeeID IN( #{employeeIds} )")
List<Employee> selectSpecificEmployees(@Param("employeeIds") List<Integer> employeeIds);
Je suis la création d'une instance de la Mapper
où l'annotation ci-dessus est défini en l'appelant comme suit:
List<Integer> empIds = Arrays.asList(1, 2, 3);
List<Employee> result = mapper.selectSpecificEmployees(empIds);
J'ai découvert que cela ne fonctionne pas.
org.apache.ibatis.des exceptions.PersistenceException:
### Erreur lors de l'interrogation de la base de données. Cause: java.lang.NullPointerException
### L'erreur peut impliquer
com.mycompany.MySourceMapper.selectSpecificEmployees-Inline
### L'erreur s'est produite pendant la configuration des paramètres
### Cause: java.lang.NullPointerException
au org.apache.ibatis.des exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
au org.apache.ibatis.session.les valeurs par défaut.DefaultSqlSession.selectList(DefaultSqlSession.java:77)
au org.apache.ibatis.session.les valeurs par défaut.DefaultSqlSession.selectList(DefaultSqlSession.java:69)
au org.apache.ibatis.de liaison.MapperMethod.executeForList(MapperMethod.java:85)
au org.apache.ibatis.de liaison.MapperMethod.execute(MapperMethod.java:65)
au org.apache.ibatis.de liaison.MapperProxy.invoke(MapperProxy.java:35)
à $Proxy23.selectSpecificProductTypes(Source Inconnue)
au com.mycompany.MySourceMapperDebug.testSelectSpecificEmployees(MySourceMapperDebug.java:60)
au coucher du soleil.de réfléchir.NativeMethodAccessorImpl.invoke0(Native method)
au coucher du soleil.de réfléchir.NativeMethodAccessorImpl.invoke(Source Inconnue)
au coucher du soleil.de réfléchir.DelegatingMethodAccessorImpl.invoke(Source Inconnue)
à java.lang.de réfléchir.La méthode.invoke(Source Inconnue)
à junit.cadre.Cas de test.runTest(cas de test.java:154)
à junit.cadre.Cas de test.runBare(cas de test.java:127)
à junit.cadre.Verdict$1.protéger(Verdict.java:106)
à junit.cadre.Verdict du test.runProtected(Verdict.java:124)
à junit.cadre.Verdict du test.exécuter(Verdict.java:109)
à junit.cadre.Cas de test.exécuter(cas de test.java:118)
à junit.cadre.TestSuite.runTest(TestSuite.java:208)
à junit.cadre.TestSuite.exécuter(TestSuite.java:203)
au org.eclipse.jdt.interne.junit.runner.junit3.JUnit3TestReference.exécuter(JUnit3TestReference.java:130)
au org.eclipse.jdt.interne.junit.runner.TestExecution.exécuter(TestExecution.java:38)
au org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
au org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
au org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.exécuter(RemoteTestRunner.java:390)
au org.eclipse.jdt.interne.junit.runner.RemoteTestRunner.principale(RemoteTestRunner.java:197)
Causés par: java.lang.NullPointerException
au org.apache.ibatis.type.UnknownTypeHandler.setNonNullParameter(UnknownTypeHandler.java:21)
au org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:23)
au org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:73)
au org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:61)
au org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:43)
au org.apache.ibatis.exécuteur testamentaire.SimpleExecutor.prepareStatement(SimpleExecutor.java:56)
au org.apache.ibatis.exécuteur testamentaire.SimpleExecutor.doQuery(SimpleExecutor.java:40)
au org.apache.ibatis.exécuteur testamentaire.BaseExecutor.queryFromDatabase(BaseExecutor.java:216)
au org.apache.ibatis.exécuteur testamentaire.BaseExecutor.requête(BaseExecutor.java:95)
au org.apache.ibatis.exécuteur testamentaire.CachingExecutor.requête(CachingExecutor.java:72)
au coucher du soleil.de réfléchir.NativeMethodAccessorImpl.invoke0(Native method)
au coucher du soleil.de réfléchir.NativeMethodAccessorImpl.invoke(Source Inconnue)
au coucher du soleil.de réfléchir.DelegatingMethodAccessorImpl.invoke(Source Inconnue)
à java.lang.de réfléchir.La méthode.invoke(Source Inconnue)
au org.apache.ibatis.plugin.Invocation.procéder(Invocation.java:31)
... 36 plus
Je pense que le problème est dans l'annotation elle-même. Cela semble comme il serait assez exigence commune. Ai-je besoin pour convertir le List
à un String
moi-même et le passer dans un String
paramètre au lieu d'une List<Integer>
? Ou est-il une autre syntaxe pour passer un List
comme paramètre de MyBatis annotation?
- Vous pouvez utiliser xml et d'annotation basé config ensemble oeil à ce poste, veuillez stackoverflow.com/questions/8788250/...
Vous devez vous connecter pour publier un commentaire.
Je n'ai jamais utilisé d'annotations et de MyBatis avant; j'ai toujours pris le fichier de configuration xml route (impliquant pas il ya quelque chose de mal avec l'aide d'annotations; il suffit d'expliquer que je ne peux pas vous aider là-bas).
Cela étant dit, page 46 de la MyBatis guide de l'utilisateur:
SELECT * FROM POST P WHERE ID = list.get(0)
Veuillez me suggérer, comment pouvons-nous faire cela.Avec un peu de surcharge, vous pouvez utiliser JAVA pour construire une Chaîne dynamique après le traitement de la Liste.
Définir Sélectionnez un Fournisseur où vous pouvez construire votre requête dynamique:
Dans com.data.sqlprovider.EmployeeSQLBuilder.class , à l'Aide de StringBuilder, de générer la requête
Je me pose exactement les mêmes questions récemment. Pour ma compréhension, vous préférez utiliser
Java
mappeur au lieu deXML
, qui est la même chose ici.Qui suit est ce que je fais de traiter avec elle en utilisant: SqlBuilder.
Le générateur sql classe:
Le mappeur:
Que c'est.
La
EmployeeSqlBuilder
va générer dynamiquement l'instruction sql. Je suis à l'aide d'une fonctiongetSqlConditionCollection
à faire de la logique de la manipulation. Bien sûr, vous pouvez encapsuler lagetSqlConditionCollection
comme une fonction statique dans une classe, qui est ce que je fais dans le projet réel, alors vous pouvez l'utiliser facilement d'autres SqlBuilder.Si vous souhaitez utiliser
foreach
et d'annotations, vous pouvez utiliser cette syntaxe:(copié à partir de cette réponse)
MyBatis Liste de soutien params directement.
Suppose que c'est vous dao couche:
vous souhaitez passer un id de liste.
puis, en vous mapper.xml, vous pouvez simplement utiliser:
vous pouvez utiliser
#{list[0]}
ou#{list[1]}
pour obtenir une valeur de liste.IN(#{list})
cas qui n'est pas pris en charge, de sorte que nous sommes coincés avec mybatis.org/mybatis-3/dynamic-sql.html?#foreach