Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我可以将列表作为参数传递给MyBatis映射器吗?_Java_Mybatis - Fatal编程技术网

Java 我可以将列表作为参数传递给MyBatis映射器吗?

Java 我可以将列表作为参数传递给MyBatis映射器吗?,java,mybatis,Java,Mybatis,我试图在MyBatis中定义一个简单的@Select注释,以根据in子句定义的条件获取对象集合。SQL看起来像: SELECT * FROM employees WHERE employeeID IN (1, 2, 3); @Select("SELECT * FROM employees WHERE employeeID IN( #{employeeIds} )") List<Employee> selectSpecificEmployees(@Param("employeeIds

我试图在MyBatis中定义一个简单的
@Select
注释,以根据in子句定义的条件获取对象集合。SQL看起来像:

SELECT * FROM employees WHERE employeeID IN (1, 2, 3);
@Select("SELECT * FROM employees WHERE employeeID IN( #{employeeIds} )")
List<Employee> selectSpecificEmployees(@Param("employeeIds") List<Integer> employeeIds);
这个列表是动态生成的,所以我不知道它会有多少个参数。我只想传入一个
值列表
,类似于:

SELECT * FROM employees WHERE employeeID IN (1, 2, 3);
@Select("SELECT * FROM employees WHERE employeeID IN( #{employeeIds} )")
List<Employee> selectSpecificEmployees(@Param("employeeIds") List<Integer> employeeIds);
我发现这不管用

org.apache.ibatis.exceptions.PersistenceException:
###查询数据库时出错。原因:java.lang.NullPointerException
###错误可能涉及
com.mycompany.mysourceapper.selectSpecificEmployeesInline
###设置参数时出错 ###原因: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。选择SpecificProductTypes(未知来源) 在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) 运行(TestResult.java:109) 运行(TestCase.java:118) 位于junit.framework.TestSuite.runTest(TestSuite.java:208) 运行(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.procedure(Invocation.java:31)
... 36多


我认为问题在于注释本身。这似乎是一个相当普遍的要求。我是否需要将
列表
转换为
字符串
并将其作为
字符串
参数而不是
列表
?或者是否有其他语法将
列表作为参数传递给MyBatis批注?

我以前从未使用过批注和MyBatis;我一直遵循xml配置文件的路线(并不意味着使用注释有什么问题;只是解释一下我在这方面帮不了你)

话虽如此,但:

foreach

动态SQL的另一个常见需求是需要迭代 收集,通常用于建立一个内部条件。例如:


挑选*
从邮政P
我在哪里
#{item}
foreach元素非常强大,允许您指定 集合、声明可在内部使用的项和索引变量 元素的主体。它还允许您指定洞口和洞口 关闭字符串,并在迭代之间添加分隔符。 该元素是智能的,因为它不会意外地附加额外的 分离器


在处理列表后,您可以使用JAVA构建一个动态字符串,这需要一些开销

  • 定义可在其中生成动态查询的选择提供程序:

    @SelectProvider(type = com.data.sqlprovider.EmployeeSQLBuilder.class, method =      
     "selectSpecificEmployees")
     List<Employee> selectSpecificEmployees(@Param("employeeIds") List<Integer> 
      employeeIds);
    
    @SelectProvider(type=com.data.sqlprovider.EmployeeSQLBuilder.class,方法=
    “选择特定员工”)
    列表selectSpecificEmployees(@Param(“EmployeeId”)列表
    雇员);
    
  • 在com.data.sqlprovider.EmployeeSQLBuilder.class中,使用StringBuilder生成查询

     public String selectSpecificEmployees(Map<String, Object> parameters) {
        List<Integer> employeeIds = (List<Integer>) parameters.get("employeeIds");
        StringBuilder builder = new StringBuilder("SELECT id, name FROM employees where id IN (");
        for (int i : employeeIds) {
            builder.append(i + ",");
        }
        builder.deleteCharAt(builder.length() - 1);
    
        builder.append(")");
        System.out.println(builder.toString());
        return builder.toString();
    }
    
    公共字符串selectSpecificEmployees(映射参数){
    列出员工ID=(Lis)
    
    @Select("<script>" +
             "SELECT * FROM employees WHERE employeeID IN " +
               "<foreach item='item' index='index' collection='employeeIds'" +
                 " open='(' separator=',' close=')'>" +
                 " #{item}" +
               "</foreach>" +
             "</script>") 
    List<Employee> selectSpecificEmployees(@Param("employeeIds") List<Integer> employeeIds);
    
    public class EmployeeSqlBuilder {
    
        public String getEmployees(final List employeeIds) {
    
            String strSQL = new SQL() {{
                SELECT("*");
                FROM("employees");
                if (employeeIds != null) {
                    WHERE(getSqlConditionCollection("employeeID", employeeIds));
                }
            }}.toString();
    
            return strSQL;
        }
    
        private String getSqlConditionCollection(String field, List conditions) {
            String strConditions = "";
            if (conditions != null && conditions.size() > 0) {
                int count = conditions.size();
                for (int i = 0; i < count; i++) {
                    String condition = conditions.get(i).toString();
    
                    strConditions += condition;
                    if (i < count - 1) {
                        strConditions += ",";
                    }
                }
                return field + " in (" + strConditions + ")";
            } else {
                return "1=1";
            }
        }
    
    }
    
    @SelectProvider(type = EmployeeSqlBuilder.class, method = "getEmployees")
    List<RecordSubjectEx> getEmployees(@Param("employeeIds") List employeeIds);