关于Mybatis中使用foreach循环时,空集合导致报错的经历
定位问题
首先定位问题,通过查找日志找到这部分内容
### Error querying database. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'IN'.
### The error may exist in com/qiyuesuo/org/role/relation/RoleRelationDao.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT COUNT(*) FROM ROLE_RELATION WHERE roleId = ? AND relationId IN
### Cause: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'IN'.
; uncategorized SQLException; SQL state [S0001]; error code [102]; Incorrect syntax near 'IN'.; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'IN'.
org.springframework.jdbc.UncategorizedSQLException:
很明显是在IN符号附近出现了问题,再看下xml文件中的sql语句
<select id="count" resultType="int">
SELECT COUNT(*) FROM ROLE_RELATION WHERE roleId = #{roleId} AND relationId IN
<foreach collection="relationIds" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
没有时间看源码,问了下同事,这样写如果空集合的情况下,由于没有元素要遍历,括号就没了,而且就算有括号,括号里没有值,一样不符合sql语句规范
解决办法
第一种办法是在java语句中判断一下空集合的情况
第二种办法是在mybatis中对空集合进行判断,如下
<choose>
<when test="ids.size > 0">
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
</when>
<otherwise>
('')
</otherwise>
</choose>