mybatis3.2.8踩坑記錄之.size()

關(guān)于mybatis的xml標(biāo)簽使用問題和單元測試模擬高并發(fā)場景

標(biāo)簽使用問題

線上問題復(fù)現(xiàn)

Exception in thread "Thread-10" org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'null!=list and list.size()>0'. Cause: org.apache.ibatis.ognl.MethodFailedException: Method "size" failed for object [3] [java.lang.IllegalAccessException: Class org.apache.ibatis.ognl.OgnlRuntime can not access a member of class com.google.common.collect.Lists$TransformingRandomAccessList with modifiers "public"]
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:75)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:368)
    at com.sun.proxy.$Proxy26.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:198)

查詢對應(yīng)的xml

<select id="findUserProductDelaysByOrderNoAndProductId"
        resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from pe_user_product_delay where is_deleted = 0
        <if test="null!=list and list.size()>0">
            and status in
            <foreach collection="list" index="index" item="status" open="("
                separator="," close=")">
                #{status,jdbcType=INTEGER}
            </foreach>
        </if>
        <if test="productId != null and productId >= 0">
            and product_id =#{productId,jdbcType=INTEGER}
        </if>
        <if test="orderNo != null and orderNo !=''">
            and order_no =#{orderNo,jdbcType=VARCHAR}
        </if>
        and type in (1,2,3)
    </select>

問題就出現(xiàn)在list.size()這上面

目前的mybatis版本為3.2.8,框架對于傳入的集合的調(diào)用size方法這部分并發(fā)控制的并不好,導(dǎo)致并發(fā)量稍微一高就會導(dǎo)致拋出異常,這里有一個關(guān)于這個問題的說明

https://zhuanlan.zhihu.com/p/30085658

此處建議:

不要在mybatis的xml中做一些調(diào)用集合函數(shù)方法等,所有的判斷是否為空,判斷集合大小這種操作都放到Java代碼中執(zhí)行,現(xiàn)有已存在的代碼要盡快修改測試

單元測試模擬并發(fā)環(huán)境

public class UserProductDelayTest extends Junit4Base {
    @Autowired
    private IUserProductDelayService userProductDelayService;
    //模擬短時間內(nèi)的并發(fā)請求量
    private static final int threadNum = 20;
    //倒計時器,用于模擬高并發(fā)
    private CountDownLatch cdl = new CountDownLatch(threadNum);

    @Test
    public void demo() {
        for (int i = 0; i < threadNum; i++) {
            new Thread(new UserRequest()).start();
            //倒計時計數(shù)一次
            cdl.countDown();
        }
        try {
            //阻塞主線程,等待所有的子線程執(zhí)行完畢
            Thread.currentThread().join();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //
    private class UserRequest implements Runnable {

        @Override
        public void run() {
            try {
                cdl.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

          //此處進行寫要并發(fā)測試的代碼
            List<UserProductDelay> delayList =
                  userProductDelayService.findUserProductDelaysByOrderNoAndProductId("123123", 1, UserProductDelay.Status.AUDITEND);
            System.out.println(JSON.toJSONString(delayList));
        }
    }
}

利用CountDownLatch的特性實現(xiàn)模擬并發(fā)線程訪問,建議所有的對外提供服務(wù)的service做單元測試的時候用這種方式自測一下

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. 簡介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優(yōu)秀的...
    笨鳥慢飛閱讀 6,248評論 0 4
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當(dāng)在唯一索引所對應(yīng)的列上鍵入重復(fù)值時,會觸發(fā)此異常。 O...
    我想起個好名字閱讀 5,983評論 0 9
  • 我生性敏感,缺乏安全感和過分自卑。遇到點事常會設(shè)身處地的為他人著想,生怕自己言行舉止惹得他人不愉快,然而最后才發(fā)現(xiàn)...
    維愛之都閱讀 231評論 0 0
  • 前幾日外出遇到一位小妹妹,她的言談舉止是那么大方,對自己自信滿滿,沒有一點害羞或矜持的表現(xiàn)。 恰巧在轉(zhuǎn)接車時我倆坐...
    暗香疏影手筆閱讀 944評論 2 1
  • 1、各司其職的形狀 在我的流程圖中,適用于不同目的和功能的形狀都有各自確定的規(guī)范。一共定義了以下一些形狀: (1)...
    零一間閱讀 1,256評論 0 2

友情鏈接更多精彩內(nèi)容