select * from users where id in ()
The query is shown above.
<select id="getByIds" resultMap="BaseResultMap">
SELECT
<include refid="BaseColumnList"/>
FROM users
WHERE id IN
<foreach item="id" collection="ids"
open="(" separator="," close=")">
#{id}
</foreach>
</select>
If the Param ids
is empty, Mybatis will throw BadSqlGrammarException, which generate a query like 'select * from users where id in
'.
How can I skip query and return empty list if ids
is empty?
How can I skip query and return empty list if ids is empty?
To skip the query (not execute it), just don't call Mybatis. The calling code should check if ids is empty:
return null == ids || ids.isEmpty() ? new ArrayList<User>() : session.select("getByIds", ids);
This is exactly what is asked in the question.
If you really want Mybatis to handle this, then produced query must be valid because must be executed (then not skipped) to return empty result quickly. that means forget something like id = <!-- a value that will never exist in the table -->
because it could surely involve a (free and useless) full scan to search the unexisting value.
Then:
WHERE
<choose>
<when test="ids==null || ids.isEmpty()">
1 = 0 <!-- a test returning false, to adapt depending on you DB vendor -->
</when>
<otherwise>
id IN <foreach item="id" collection="ids" open="(" separator="," close=")">#{id}</foreach>
</otherwise>
</choose>
Another option to confirm would consist in using interceptors to "cancel" the query before its execution, but this is definitely overkill complexity for what has to be achieved here.