我可以将列表作为参数传递给MyBatis映射器吗? [英] Can I pass a List as a parameter to a MyBatis mapper?

查看:72
本文介绍了我可以将列表作为参数传递给MyBatis映射器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在MyBatis中定义一个简单的@Select批注,以基于由IN子句定义的条件来获取对象的集合. SQL看起来像:

I'm trying to define a simple @Select annotation in MyBatis to get a collection of objects based on criteria defined by an IN clause. The SQL looks something like:

SELECT * FROM employees WHERE employeeID IN (1, 2, 3);

该列表是动态生成的,因此我不知道它将具有多少个参数.我只想传递List值,例如:

The list is generated dynamically, so I don't know how many parameters it will have. I'd like to just pass in a List of values, something like:

@Select("SELECT * FROM employees WHERE employeeID IN( #{employeeIds} )")
List<Employee> selectSpecificEmployees(@Param("employeeIds") List<Integer> employeeIds);

我正在创建Mapper的实例,在其中定义了上面的注释,并按如下方式调用它:

I'm creating an instance of the Mapper where the annotation above is defined and calling it as follows:

List<Integer> empIds = Arrays.asList(1, 2, 3);
List<Employee> result = mapper.selectSpecificEmployees(empIds);

我发现这行不通.

org.apache.ibatis.exceptions.PersistenceException:
###查询数据库时出错.原因:java.lang.NullPointerException
###错误可能涉及
com.mycompany.MySourceMapper.selectSpecificEmployees-Inline
###设置参数时发生错误 ###原因:java.lang.NullPointerException 在org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8) 在org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:77) 在org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:69) 在org.apache.ibatis.binding.MapperMethod.executeForList(MapperMethod.java:85) 在org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:65) 在org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:35) 在$ Proxy23.selectSpecificProductTypes(未知来源) 在com.mycompany.MySourceMapperDebug.testSelectSpecificEmployees(MySourceMapperDebug.java:60) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 在sun.reflect.NativeMethodAccessorImpl.invoke(未知来源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源) 在java.lang.reflect.Method.invoke(未知来源) 在junit.framework.TestCase.runTest(TestCase.java:154) 在junit.framework.TestCase.runBare(TestCase.java:127) 在junit.framework.TestResult $ 1.protect(TestResult.java:106) 在junit.framework.TestResult.runProtected(TestResult.java:124) 在junit.framework.TestResult.run(TestResult.java:109) 在junit.framework.TestCase.run(TestCase.java:118) 在junit.framework.TestSuite.runTest(TestSuite.java:208) 在junit.framework.TestSuite.run(TestSuite.java:203) 在org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130) 在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)上 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 造成原因:java.lang.NullPointerException 在org.apache.ibatis.type.UnknownTypeHandler.setNonNullParameter(UnknownTypeHandler.java:21) 在org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:23) 在org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:73) 在org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:61)上 在org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:43) 在org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:56) 在org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:40) 在org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:216) 在org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:95) 在org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:72) 在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处 在sun.reflect.NativeMethodAccessorImpl.invoke(未知来源) 在sun.reflect.DelegatingMethodAccessorImpl.invoke(未知来源) 在java.lang.reflect.Method.invoke(未知来源) 在org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:31)
...另外36个

org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.lang.NullPointerException
### The error may involve
com.mycompany.MySourceMapper.selectSpecificEmployees-Inline
### The error occurred while setting parameters ### Cause: java.lang.NullPointerException at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:77) at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:69) at org.apache.ibatis.binding.MapperMethod.executeForList(MapperMethod.java:85) at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:65) at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:35) at $Proxy23.selectSpecificProductTypes(Unknown Source) at com.mycompany.MySourceMapperDebug.testSelectSpecificEmployees(MySourceMapperDebug.java:60) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at junit.framework.TestCase.runTest(TestCase.java:154) at junit.framework.TestCase.runBare(TestCase.java:127) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:118) at junit.framework.TestSuite.runTest(TestSuite.java:208) at junit.framework.TestSuite.run(TestSuite.java:203) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) Caused by: java.lang.NullPointerException at org.apache.ibatis.type.UnknownTypeHandler.setNonNullParameter(UnknownTypeHandler.java:21) at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:23) at org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:73) at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:61) at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:43) at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:56) at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:40) at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:216) at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:95) at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:72) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:31)
... 36 more

我认为问题出在注释本身.这似乎是一个相当普遍的要求.我是否需要自己将List转换为String并将其作为String参数而不是List<Integer>传递?还是有其他语法可以将List作为参数传递给MyBatis批注?

I think the problem is in the annotation itself. This seems like it would be a fairly common requirement. Do I need to convert the List to a String myself and pass that in as a String parameter instead of a List<Integer>? Or is there some other syntax for passing a List as a parameter to a MyBatis annotation?

推荐答案

我以前从未使用过注解和MyBatis.我一直走过xml配置文件路由(不是暗示使用批注有什么问题;只是在解释我不能为您提供帮助).

I've never used annotations and MyBatis before; I've always gone the xml configuration file route (not implying there is anything wrong with using annotations; just explaining I can't help you there).

话虽如此,《 MyBatis用户指南》中的第46页:

That being said, page 46 from the MyBatis user guide:

foreach

动态SQL的另一个常见需求是需要迭代一个 收集时,通常会建立一个IN条件.例如:

Another common necessity for dynamic SQL is the need to iterate over a collection, often to build an IN condition. For example:

<select id="selectPostIn" resultType="domain.blog.Post">
    SELECT *
    FROM POST P
    WHERE ID in
    <foreach item="item" index="index" collection="list"
        open="(" separator="," close=")">
          #{item}
    </foreach>
  </select>

foreach元素非常强大,可让您指定一个 收集,声明可以在内部使用的项目和索引变量 元素的主体.它还允许您指定打开和 关闭字符串,并添加一个分隔符以放置在两次迭代之间. 该元素很聪明,因为它不会意外地添加额外的内容 分隔符.

The foreach element is very powerful, and allows you to specify a collection, declare item and index variables that can be used inside the body of the element. It also allows you to specify opening and closing strings, and add a separator to place in between iterations. The element is smart in that it won’t accidentally append extra separators.

这篇关于我可以将列表作为参数传递给MyBatis映射器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆