Stories

Detail Return Return

MyBatis 的 in 查詢導致的bug - Stories Detail

案例

分享一個很久之前的案例。

任務是:根據運營部門提供的門店列表,查詢門店詳情並生成報表。起初,我寫了這樣一段 SQL:

<select id="selectStores" resultType="Store">
    SELECT * FROM stores
    WHERE store_code
    <foreach collection="storeIdList" item="storeId" separator="," open="(" close=")">
        #{storeCode}
    </foreach>
</select>

在做一次測試時,這次傳給我的 storeIdList 竟然是 null。結果 SQL 條件失效,整張門店表被查出來。在 <foreach> 裏直接寫 IN 條件,如果 list 為空或 null,很容易產生全表查詢風險。

改進方案

為了避免這種問題,我們儘量在代碼層面做好驗證處理。

方案1:

if (storeCodeList == null || storeCodeList.isEmpty()) {
    return Collections.emptyList(); // 空列表直接返回
}

方案2: 最好規約,不要將“in”添加在open中

<select id="selectStores" resultType="Store">
    SELECT * FROM stores where store_code in
    
    <foreach collection="storeCodeList" item="storeCode" separator="," open="(" close=")">
        #{storeCode}
    </foreach>
</select>

兩個sql 的對比:https://diffsnap.com/share/P2um8cQvBQJi

Add a new Comments

Some HTML is okay.