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

情景描述

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

错误写法一

<isNotEmpty property="idList">
    id in 
    <iterate property="idList" open="(" close=")" conjunction=",">
        <![CDATA[ #idList[]# ]]>
    </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=",">
        <![CDATA[ #idList[]# ]]>
    </iterate>
</isNotEmpty>

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

正确写法示范

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

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

<isPropertyAvailable prepend="and" property="idList">
    <isNotEmpty property="idList">
        <iterate property="idList" open="(" close=")" conjunction="or">
            <![CDATA[ id = #idList[]# ]]>
        </iterate>
    </isNotEmpty>
    <isEmpty property="idList">
        <![CDATA[ 1<>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”来代替。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TechGenius

文章很值,请作者喝一杯咖啡吧!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值