iBatis中in条件的严谨写法(list为空的情况)

情景描述

Oracle查询SQL语句,in条件比较容易出现异常,如果列表或数组为空,则会出现in ()的情况,然后执行就会抛出异常

错误写法一

<isNotEmpty property="idList">
    id in 
    <iterate property="idList" open="(" close=")" conjunction=",">
        
    iterate>
isNotEmpty>

试想,如果list为空,拼接出来的语句为 where col = 1 and ..,并没有出现预想中的 where col = 1 and id in (‘1’, ‘2’)
然后会抛异常:ORA-00936: 缺失表达式

错误写法二

<isNotEmpty property="idList">
    <iterate property="idList" open="id in (" close=")" conjunction=",">
        
    iterate>
isNotEmpty>

试想,当我们传入一个空列表的时候,由于列表中没有任何元素,iterate标签将失效(条件生成被忽略)。这样的后果非常严重,本来in一个空列表,应该是没有数据才对,却变成了获取全部数据!

正确写法示范

<isPropertyAvailable prepend="and" property="idList">
    <isNotEmpty property="idList">
        <iterate property="idList" open="Id in (" close=")" conjunction=",">
            
        iterate>
    isNotEmpty>
    <isEmpty property="idList">
        1 ]]>
    isEmpty>
isPropertyAvailable>

由于Oracle的in子句有长度限制,对于项数比较多的查询,请改用以下形式(拼成or的形式):

<isPropertyAvailable prepend="and" property="idList">
    <isNotEmpty property="idList">
        <iterate property="idList" open="(" close=")" conjunction="or">
            
        iterate>
    isNotEmpty>
    <isEmpty property="idList">
        1 ]]>
    isEmpty>
isPropertyAvailable>

首先通过isPropertyAvailable标签来判断HashMap中是否有idList这个列表参数(不能直接用isNotEmpty,因为空列表会被视为isEmpty),然后通过isNotEmpty和isEmpty进行分类判断。isNotEmpty中自然是我们熟悉的代码了;而isEmpty(iBatis中空列表和Null都会被认为是isEmpty)中只需拼上一个永远为False的条件“1<>1”即可,因为in一个空列表,SQL中是不能直接写“id in ()”的,而in一个空列表又是永远为假的条件,因此可以用“1<>1”来代替。

你可能感兴趣的:(IBatis学习笔记)