使用mybatis注释

时间:2016-07-06 14:35:54

标签: java database oracle annotations mybatis

我试图在由SELECT子句组成的SELECT QUERY中传递多个值。我想使用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);

我正在以这种方式构造值的字符串:

String scanIDs = StringUtils.join(cmp.getChildScanIDs(), ",");

执行该功能时,会引发此异常。

### 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没有将值识别为单独的数字。另一种解决方案是对每个数字执行查询,但我想一次传递所有值。 提前致谢。

2 个答案:

答案 0 :(得分:2)

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')

如您所见,该值被视为String而不是列表,这不是您所需要的。

我会将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>

它的作用:

  • &lt; foreach&gt;:启动foreach循环
  • item:循环内当前对象的名称
  • index:索引变量(在这种情况下不是真的需要)
  • collection:集合的名称(根据您在mapper界面中的定义)
  • open:在第一次迭代之前插入的字符串
  • close:在最后一次迭代后插入的字符串
  • separator:要在元素和另一个
  • 之间插入的字符串
  • #{item}:打印当前项目

参考链接:MyBatis Dynamic SQL

答案 1 :(得分:1)

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

所以你可以创建

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

并在查询中将其用作

WHERE SCAN_ID IN (${@InList@build(childScanIds)})

注意:使用${}会打开意外或故意的SQL注入问题,但显然这也取决于您的用例,因此请谨慎使用。