Java 使用mybatis注释在in子句中传递多个值

Java 使用mybatis注释在in子句中传递多个值,java,database,oracle,annotations,mybatis,Java,Database,Oracle,Annotations,Mybatis,我试图在包含in子句的SELECT查询中传递多个值。我想使用mybatis执行以下查询: SELECT * FROM DBA_COMPARISON_ROW_DIF WHERE SCAN_ID in (#{childScanIDs}) 其中,childScanIDs变量由多个逗号分隔的值组成。我将这些值作为一个字符串传递,该字符串由用逗号分隔的所有值组成。下面是mapper界面中使用的方法 @Select(getDifferencesByScanIDs) @Results({

我试图在包含in子句的SELECT查询中传递多个值。我想使用mybatis执行以下查询:

SELECT * FROM DBA_COMPARISON_ROW_DIF WHERE SCAN_ID in  (#{childScanIDs})
其中,childScanIDs变量由多个逗号分隔的值组成。我将这些值作为一个字符串传递,该字符串由用逗号分隔的所有值组成。下面是mapper界面中使用的方法

@Select(getDifferencesByScanIDs)
    @Results({
            @Result(property="owner", column="OWNER"),
            @Result(property="comparisonName", column="COMPARISON_NAME"),
            @Result(property="scanID", column="SCAN_ID"),
            @Result(property="localRowID", column="LOCAL_ROWID"),
            @Result(property="remoteRowID", column="REMOTE_ROWID"),
            @Result(property="indexValue", column="INDEX_VALUE"),
            @Result(property="status", column="STATUS"),
            @Result(property="lastUpdateTime", column="LAST_UPDATE_TIME")
    })
    List<Difference> getDifferencesByScanIDs(@Param("childScanIDs") String childScanIDs);
在执行函数时,它会引发此异常

### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: ORA-01722: invalid number

### The error may involve com.rs2.automation.soacomparison.dao.differences.DifferencesMapper.getDifferencesByScanIDs-Inline
### The error occurred while setting parameters
### Cause: java.sql.SQLSyntaxErrorException: ORA-01722: invalid number
任何帮助都将不胜感激。我认为问题在于mybatis没有将这些值识别为单独的数字。另一个解决方案是对每个数字执行查询,但我希望一次传递所有值。 提前谢谢

SELECT * FROM DBA_COMPARISON_ROW_DIF WHERE SCAN_ID in  (#{childScanIDs})
如果我们想象一个类似于2、13、15、16的列表,这个查询将导致:

SELECT * FROM DBA_COMPARISON_ROW_DIF WHERE SCAN_ID in  ('2,13,15,16')
如您所见,该值被视为字符串而不是列表,这不是您所需要的

我将把cmp.getChildScanIDs传递给mybatis,而不将其转换为字符串,并使用mybatis的动态sql

将该方法编辑为:

List<Difference> getDifferencesByScanIDs(@Param("childScanIDs") List<Integer> childScanIDs); // or int[]
将查询编辑为:

SELECT * FROM DBA_COMPARISON_ROW_DIF WHERE SCAN_ID in 
    <foreach item="item" index="index" collection="childScanIDs" open="(" separator="," close=")">
    #{item}
    </foreach>
它的作用是:

:启动foreach循环 item:循环中当前对象的名称 index:在这种情况下实际上不需要index变量 集合:集合的名称,符合映射器界面中的定义 打开:在第一次迭代之前插入的字符串 关闭:上次迭代后要插入的字符串 分隔符:在元素和另一个元素之间插入的字符串 {item}:打印当前项
参考链接:

这在文档中不是很清楚。有几种方法可以做到这一点,但直接的方法是只使用OGNL。我们通过OGNL评估文档中解释的任何参数{xx}或${xx}差异

例如,您可以创建

public class InList {
    public static String build(final List<?> params) {
        return Joiner.on(",").join(params);
    }
}

注意:使用${}会导致意外或有意的SQL注入问题,但很明显,这也取决于您的用例,所以请小心使用。

谢谢。我尝试了这个解决方案,但它给了我一个错误:查询数据库时出错。原因:org.apache.ibatis.type.TypeException:设置null参数时出错。大多数JDBC驱动程序要求必须为所有可空参数指定JdbcType。原因:java.sql.SQLException:列类型无效:1111@gla315尝试告诉mybatis item是哪种类型:在ForEachTested中用{item,jdbcType=INTEGER}替换{item},但它给出的SQL语句无效。这是查询:@Select{,Select*,FROM DBA_COMPARISON_ROW_DIF,其中SCAN_ID IN,,{item,jdbcType=INTEGER},,}这是我传递整数列表的方式:list list list=new arraraylist;forString st:cmp.getChildScanIDs{Integer intNum=new Integerst;list.addintNum;}list differences=mapperLocal.getDifferencesByScanIDslist@gla315我不知道自2013年以来是否发生了一些变化,但如前所述,动态sql可能不适用于注释。为了解决您的问题,您需要动态sql,因此如果您想要使用它,您需要支持基于XML的映射器,这在IMO中也更好,因为您将java和sql逻辑分离,使事情更加清楚。
public class InList {
    public static String build(final List<?> params) {
        return Joiner.on(",").join(params);
    }
}
WHERE SCAN_ID IN (${@InList@build(childScanIds)})