如果MyBatis 3中where_in子句为空,我如何跳过查询?

wwu*_*ric 10 mybatis

select * from users where id in ()
Run Code Online (Sandbox Code Playgroud)

查询如上所示.

<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>
Run Code Online (Sandbox Code Playgroud)

如果Param ids为空,Mybatis将抛出BadSqlGrammarException,它会生成类似' select * from users where id in' 的查询.

如果ids为空,我如何跳过查询并返回空列表?

bla*_*ard 6

如果ids为空,我如何跳过查询并返回空列表?

跳过查询(不执行它),只需不要调用Mybatis.调用代码应该检查id是否为空:

return null == ids || ids.isEmpty() ? new ArrayList<User>() : session.select("getByIds", ids);
Run Code Online (Sandbox Code Playgroud)

这正是问题中提出的问题.

如果你真的希望Mybatis处理这个问题,那么生成的查询必须是有效的,因为必须执行(然后不要跳过)才能快速返回空结果.这意味着忘记一些事情, id = <!-- a value that will never exist in the table -->因为它肯定会涉及一个(自由和无用的)全扫描来搜索未存在的值.然后:

    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>
Run Code Online (Sandbox Code Playgroud)

确认的另一个选项是使用拦截器在执行之前"取消"查询,但这绝对是过度的复杂性,必须在这里实现.


小智 5

java代码函数

 List<ApiPriceChlogEntity> getApiAndDevPrice(@Param("apiKeys") List<String> currentApiKey, @Param("devKeys") List<String> currentDevKey, @Param("startDate") Date startDate);
Run Code Online (Sandbox Code Playgroud)

映射器文件

<select id="getApiAndDevPrice"  resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM t_api_price_chlog tab1
<where>
    <if test="apiKeys.size() > 0">
      tab1.api_key IN
      <foreach collection="apiKeys" item="item" separator="," open="(" close=")" index="">
        #{item}
      </foreach>
    </if>
    <if test="devKeys.size() > 0">
      AND tab1.dev_key IN
      <foreach collection="devKeys" item="item" separator="," open="(" close=")" index="">
        #{item}
      </foreach>
    </if>

    <if test="startDate != null">
      AND tab1.change_date >= #{startDate}
    </if>
</where>
Run Code Online (Sandbox Code Playgroud)

我已经测试过了,希望能帮到你。

  • 如果参数没有值,这会导致查询所有数据 (3认同)