使用 mybatis 注解在 IN 子句中传递多个值
Pass multiple values in IN clause using mybatis annotations
我试图在 SELECT 包含 IN 子句的查询中传递多个值。我想使用 mybatis 执行以下查询:
SELECT * FROM DBA_COMPARISON_ROW_DIF WHERE SCAN_ID in (#{childScanIDs})
其中 childScanIDs
变量由多个逗号分隔值组成。我将这些值作为一个字符串传递,该字符串由用逗号分隔的所有值组成。下面是映射器接口中使用的方法。
@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 没有将这些值识别为单独的数字。另一种解决方案是对每个数字执行查询,但我想一次传递所有值。
提前致谢。
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>
它的作用:
: 开始一个 foreach 循环
- item: 循环内当前对象的名称
- index:索引变量(在这种情况下并不真正需要)
- collection:集合的名称(根据您在映射器接口中的定义)
- open: 在第一次迭代之前插入的字符串
- 关闭:最后一次迭代后要插入的字符串
- 分隔符:要在一个元素和另一个元素之间插入的字符串
- #{item}: 打印当前项目
Link供参考:MyBatis Dynamic SQL
这在文档中不是很清楚。有几种方法可以做到这一点,但直接的方法是只使用 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 注入问题,但显然,这也取决于您的用例,因此请谨慎使用。
我试图在 SELECT 包含 IN 子句的查询中传递多个值。我想使用 mybatis 执行以下查询:
SELECT * FROM DBA_COMPARISON_ROW_DIF WHERE SCAN_ID in (#{childScanIDs})
其中 childScanIDs
变量由多个逗号分隔值组成。我将这些值作为一个字符串传递,该字符串由用逗号分隔的所有值组成。下面是映射器接口中使用的方法。
@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 没有将这些值识别为单独的数字。另一种解决方案是对每个数字执行查询,但我想一次传递所有值。 提前致谢。
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>
它的作用:
: 开始一个 foreach 循环 - item: 循环内当前对象的名称
- index:索引变量(在这种情况下并不真正需要)
- collection:集合的名称(根据您在映射器接口中的定义)
- open: 在第一次迭代之前插入的字符串
- 关闭:最后一次迭代后要插入的字符串
- 分隔符:要在一个元素和另一个元素之间插入的字符串
- #{item}: 打印当前项目
Link供参考:MyBatis Dynamic SQL
这在文档中不是很清楚。有几种方法可以做到这一点,但直接的方法是只使用 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 注入问题,但显然,这也取决于您的用例,因此请谨慎使用。