日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

盤(pán)點(diǎn) Mybatis 使用過(guò)程中遇到的坑!

來(lái)源: 責(zé)編: 時(shí)間:2024-09-10 09:47:53 122觀看
導(dǎo)讀01、引言大家好,我是了不起,前一段時(shí)間在工作中因?yàn)橐粋€(gè)疏忽踩了一個(gè)坑,最終通過(guò)異常棧追溯源碼解決了問(wèn)題。下面我來(lái)給大家還原一下案發(fā)現(xiàn)場(chǎng),并介紹一下自己的解決思路,希望能對(duì)大家有所啟發(fā)。02、案發(fā)現(xiàn)場(chǎng)當(dāng)時(shí)的業(yè)務(wù)邏輯

01、引言

大家好,我是了不起,前一段時(shí)間在工作中因?yàn)橐粋€(gè)疏忽踩了一個(gè)坑,最終通過(guò)異常棧追溯源碼解決了問(wèn)題。xu728資訊網(wǎng)——每日最新資訊28at.com

下面我來(lái)給大家還原一下案發(fā)現(xiàn)場(chǎng),并介紹一下自己的解決思路,希望能對(duì)大家有所啟發(fā)。xu728資訊網(wǎng)——每日最新資訊28at.com

02、案發(fā)現(xiàn)場(chǎng)

當(dāng)時(shí)的業(yè)務(wù)邏輯主要通過(guò) Mybatis 框架來(lái)修改數(shù)據(jù),具體示例如下:xu728資訊網(wǎng)——每日最新資訊28at.com

import org.springframework.data.repository.query.Param;public interface GroupMapper {  int updateGroup(@Param("oldSerial") Set<Integer> oldSerial, @Param("newSerial") int newSerial); int invalidGroup(@Param("set") Set<Integer> set);}
<update id="updateGroup">    update groupCode_table_use    set groupCode=#{newSerial}    where groupCode in    <foreach collection="oldSerial" close=")" open="(" item="item" separator=",">        #{item}    </foreach></update><update id="invalidGroup">    update groupCode_table    set status='無(wú)效'    where groupCode in    <foreach collection="set" close=")" open="(" item="item" separator=",">        #{item}    </foreach></update>

本以為 so easy 的代碼,出現(xiàn)意外了!第一個(gè)sql語(yǔ)句updateGroup正常運(yùn)行,第二個(gè)sql語(yǔ)句invalidGroup竟然報(bào)錯(cuò)了???xu728資訊網(wǎng)——每日最新資訊28at.com

報(bào)錯(cuò)信息如下:xu728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片xu728資訊網(wǎng)——每日最新資訊28at.com

從日志上可以看出,提示set參數(shù)找不到!xu728資訊網(wǎng)——每日最新資訊28at.com

明明使用了@Param("set")將參數(shù)命名為set為何找不到,完全不符合多年開(kāi)發(fā)的認(rèn)知。xu728資訊網(wǎng)——每日最新資訊28at.com

更加詭異的是updateGroup已使用了同樣的方式去遍歷,完全沒(méi)得問(wèn)題,那么問(wèn)題出現(xiàn)在了哪了?xu728資訊網(wǎng)——每日最新資訊28at.com

小伙伴可以先猜一猜!xu728資訊網(wǎng)——每日最新資訊28at.com

03、原因分析

百思不得其解下,我掏出了祖?zhèn)鹘^活 debug 源碼,最終發(fā)現(xiàn)原來(lái)是Mybatis對(duì)集合Set進(jìn)行了特殊處理。xu728資訊網(wǎng)——每日最新資訊28at.com

案發(fā)項(xiàng)目引入的Mybatis版本是 3.5.1。部分源碼如下!xu728資訊網(wǎng)——每日最新資訊28at.com

org.apache.ibatis.session.defaults.DefaultSqlSession.java@Overridepublic int update(String statement, Object parameter) {  try {    dirty = true;    MappedStatement ms = configuration.getMappedStatement(statement);    //調(diào)用了wrapCollection方法對(duì)參數(shù)進(jìn)行了處理    return executor.update(ms, wrapCollection(parameter));  } catch (Exception e) {    throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);  } finally {    ErrorContext.instance().reset();  }}/*** 如果參數(shù)實(shí)現(xiàn)了Collection接口或是數(shù)組類型 wrapCollection方法會(huì)對(duì)參數(shù)進(jìn)行封裝* 如果參數(shù)實(shí)現(xiàn)了Collection接口會(huì)封裝為含collection鍵的Map*     如果參數(shù)又實(shí)現(xiàn)了List接口會(huì)封裝為含list鍵的Map(追增)*     對(duì)Set集合沒(méi)有特殊處理* 如果參數(shù)是數(shù)組類型會(huì)封裝為含array鍵的Map*/private Object wrapCollection(final Object object) {  if (object instanceof Collection) {    StrictMap<Object> map = new StrictMap<>();    map.put("collection", object);    if (object instanceof List) {      map.put("list", object);    }    return map;  } else if (object != null && object.getClass().isArray()) {    StrictMap<Object> map = new StrictMap<>();    map.put("array", object);    return map;  }  return object;}

通過(guò)以上的源碼分析,發(fā)現(xiàn)Mybatis框架對(duì)集合參數(shù)進(jìn)行了特殊處理。xu728資訊網(wǎng)——每日最新資訊28at.com

這就是為什么報(bào)錯(cuò)信息中提示Available parameters are [collection]。xu728資訊網(wǎng)——每日最新資訊28at.com

找到了collection錯(cuò)誤信息從哪里來(lái)問(wèn)題,接下來(lái)我們分析一下set參數(shù)到了哪里去。xu728資訊網(wǎng)——每日最新資訊28at.com

首先updateGroup可以正常執(zhí)行是因?yàn)樵创a中對(duì)集合的特殊處理只對(duì)單參數(shù)生效,也就是說(shuō)@Param("set")注解失效是因?yàn)楸籑ybatis自家的特殊處理給覆蓋了?xu728資訊網(wǎng)——每日最新資訊28at.com

這不合乎常理啊,那么問(wèn)題可能出在@Param注解身上,通過(guò)排查代碼發(fā)現(xiàn)GroupMapper.java類引用的@Param注解不對(duì)!xu728資訊網(wǎng)——每日最新資訊28at.com

// 代碼引入的注解類Paramimport org.springframework.data.repository.query.Param;// 期望的注解類,應(yīng)該由mybatis提供import org.apache.ibatis.annotations.Param;

實(shí)際上,springframework包下的@Param注解執(zhí)行時(shí)機(jī)在wrapCollection處理之前,wrapCollection對(duì)集合的特殊處理將springframework包下的@Param注解處理覆蓋掉了,所以無(wú)法解析參數(shù)set。而mybatis包下的@Param注解執(zhí)行時(shí)機(jī)在wrapCollection處理之后,程序可以正常運(yùn)行。xu728資訊網(wǎng)——每日最新資訊28at.com

最終確定,繞了這么大一圈,原來(lái)是包導(dǎo)入錯(cuò)了,誰(shuí)能想到springframework包下還有一個(gè)@Param注解,在多參數(shù)的情況下竟然可以正常使用o(╥﹏╥)o。xu728資訊網(wǎng)——每日最新資訊28at.com

04、異常棧分析法

整個(gè)異常排查過(guò)程中,主要通過(guò)分析異常棧信息進(jìn)行快速定位。下面我給大家介紹一下異常棧分析法。xu728資訊網(wǎng)——每日最新資訊28at.com

我們?cè)诠ぷ髦胁榭串惓#际菢I(yè)務(wù)代碼異常導(dǎo)致的,這個(gè)時(shí)候我們只需要關(guān)心是在我們編寫(xiě)的哪段代碼中出了問(wèn)題。xu728資訊網(wǎng)——每日最新資訊28at.com

而這時(shí)好用的idea也會(huì)為溫馨的為我們做出提示,會(huì)在異常棧中將我們編寫(xiě)的方法位置信息標(biāo)藍(lán)處理,這樣我們就定快速定位出現(xiàn)問(wèn)題的代碼。xu728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片xu728資訊網(wǎng)——每日最新資訊28at.com

但是一旦是底層引用的jar包出現(xiàn)了異常,僅僅是這樣查看異常棧是不夠的。下面我們就以上面案例中的異常棧來(lái)帶大家分析。xu728資訊網(wǎng)——每日最新資訊28at.com

當(dāng)前異常:xu728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片xu728資訊網(wǎng)——每日最新資訊28at.com

原始異常:xu728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片xu728資訊網(wǎng)——每日最新資訊28at.com

分析流程:xu728資訊網(wǎng)——每日最新資訊28at.com

  • 異常調(diào)用棧順序:從上至下為方法調(diào)用順序的逆序,異常由異常棧的最上面的方法拋出,整個(gè)調(diào)用的入口在最下方。
  • 尋找原始異常入口技巧:檢索異常棧中與原始異常入口(最下面)拋出位置同名的方法。
  • 尋找真正異常出現(xiàn)的位置,要找最后一個(gè) Caused by 的第一行棧幀。


xu728資訊網(wǎng)——每日最新資訊28at.com

"Caused by" 是 Java 異常處理機(jī)制中的一部分,它表示當(dāng)前異常是由另一個(gè)異常引起的。在 Java 中,每個(gè) Throwable 對(duì)象都可以通過(guò) getCause() 方法獲取到原始異常,這個(gè)原始異常就是通過(guò) "Caused by" 打印出來(lái)的。xu728資訊網(wǎng)——每日最新資訊28at.com

異常棧示例代碼:

假設(shè)你在catch塊中捕獲了一個(gè)異常,并重新拋出了一個(gè)新的異常,同時(shí)保留了原始異常的信息:xu728資訊網(wǎng)——每日最新資訊28at.com

public class Example {    public static void main(String[] args) {        try {            methodThatThrowsException();        } catch (Exception e) {            throw new RuntimeException("Caught an exception", e);        }    }    public static void methodThatThrowsException() throws Exception {        throw new Exception("Original exception");    }}

當(dāng)你運(yùn)行上述代碼時(shí),控制臺(tái)輸出的異常棧信息通常會(huì)包含Caused by信息:xu728資訊網(wǎng)——每日最新資訊28at.com

java.lang.RuntimeException: Caught an exception    at Example.main(Example.java:7)Caused by: java.lang.Exception: Original exception    at Example.methodThatThrowsException(Example.java:12)    at Example.main(Example.java:5)
  • java.lang.Exception: Original exception 是原始異常。
  • java.lang.RuntimeException: Caught an exception 是新拋出的異常,并且包含了原始異常作為其原因。
  • Caused by 信息顯示了原始異常的詳細(xì)信息,這有助于調(diào)試和理解異常的來(lái)源。

如何保留原始異常信息呢?xu728資訊網(wǎng)——每日最新資訊28at.com

  • 方式一:直接傳遞原始異常:
try {     methodThatThrowsException(); } catch (Exception e) {     throw new RuntimeException("Caught an exception", e); }
  • 方式二:使用 addSuppressed 方法:
try {     methodThatThrowsException(); } catch (Exception e) {     RuntimeException newException = new RuntimeException("Caught an exception");     newException.addSuppressed(e);     throw newException; }

05、結(jié)語(yǔ)

學(xué)會(huì)查看分析異常棧,可以為我們工作大大提高效率,希望這篇文章給大家?guī)?lái)收獲,最后再送給大家一個(gè)小技巧。異常棧不僅僅可以用來(lái)排查異常哦,還可以幫助大家學(xué)習(xí)源碼,debug 源碼找不到入口怎么辦,那就創(chuàng)造一個(gè)異常!xu728資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-112730-0.html盤(pán)點(diǎn) Mybatis 使用過(guò)程中遇到的坑!

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: SpringBoot與XXL-JOB高效定時(shí)任務(wù)管理指南

下一篇: Elasticsearch 使用誤區(qū)—單次請(qǐng)求獲取大量數(shù)據(jù)

標(biāo)簽:
  • 熱門(mén)焦點(diǎn)
  • 盧偉冰長(zhǎng)文解析K60至尊版 對(duì)Redmi有著里程碑式的意義

    在今天的Redmi后性能時(shí)代戰(zhàn)略發(fā)布會(huì)結(jié)束之后,Redmi總經(jīng)理盧偉冰又帶來(lái)了一篇長(zhǎng)文,詳解了為什么 Redmi 要開(kāi)啟后性能時(shí)代?為什么選擇和 MediaTek、Pixelworks 深度合作?以及后性
  • 2023 年的 Node.js 生態(tài)系統(tǒng)

    隨著技術(shù)的不斷演進(jìn)和創(chuàng)新,Node.js 在 2023 年達(dá)到了一個(gè)新的高度。Node.js 擁有一個(gè)龐大的生態(tài)系統(tǒng),可以幫助開(kāi)發(fā)人員更快地實(shí)現(xiàn)復(fù)雜的應(yīng)用。本文就來(lái)看看 Node.js 最新的生
  • 把LangChain跑起來(lái)的三個(gè)方法

    使用LangChain開(kāi)發(fā)LLM應(yīng)用時(shí),需要機(jī)器進(jìn)行GLM部署,好多同學(xué)第一步就被勸退了,那么如何繞過(guò)這個(gè)步驟先學(xué)習(xí)LLM模型的應(yīng)用,對(duì)Langchain進(jìn)行快速上手?本片講解3個(gè)把LangChain跑起來(lái)
  • JavaScript學(xué)習(xí) -AES加密算法

    引言在當(dāng)今數(shù)字化時(shí)代,前端應(yīng)用程序扮演著重要角色,用戶的敏感數(shù)據(jù)經(jīng)常在前端進(jìn)行加密和解密操作。然而,這樣的操作在網(wǎng)絡(luò)傳輸和存儲(chǔ)中可能會(huì)受到惡意攻擊的威脅。為了確保數(shù)據(jù)
  • 阿里大調(diào)整

    來(lái)源:產(chǎn)品劉有媒體報(bào)道稱,近期淘寶天貓集團(tuán)啟動(dòng)了近年來(lái)最大的人力制度改革,涉及員工績(jī)效、層級(jí)體系等多個(gè)核心事項(xiàng),目前已形成一個(gè)初步的&ldquo;征求意見(jiàn)版&rdquo;:1、取消P序列
  • 阿里瓴羊One推出背后,零售企業(yè)迎數(shù)字化新解

    作者:劉曠近年來(lái)隨著數(shù)字經(jīng)濟(jì)的高速發(fā)展,各式各樣的SaaS應(yīng)用服務(wù)更是層出不窮,但本質(zhì)上SaaS大多局限于單一業(yè)務(wù)流層面,對(duì)用戶核心關(guān)切的增長(zhǎng)問(wèn)題等則沒(méi)有提供更好的解法。在Saa
  • iQOO Neo8 Pro搶先上架:首發(fā)天璣9200+ 安卓性能之王

    經(jīng)過(guò)了一段時(shí)間的密集爆料,昨日iQOO官方如期對(duì)外宣布:將于5月23日推出全新的iQOO Neo8系列新品,官方稱這是一款擁有旗艦級(jí)性能調(diào)校的作品。隨著發(fā)布時(shí)
  • 華為舉行春季智慧辦公新品發(fā)布會(huì) 首次推出電子墨水屏平板

    北京時(shí)間2月27日晚,華為在巴塞羅那舉行春季智慧辦公新品發(fā)布會(huì),在海外市場(chǎng)推出之前已經(jīng)在中國(guó)市場(chǎng)上市的筆記本、平板、激光打印機(jī)等辦公產(chǎn)品,并首次推出搭載
  • 英特爾Xe HPG游戲顯卡:擁有512EU,單風(fēng)扇版本

    據(jù)10 月 30 日外媒 TheVerge 消息報(bào)道,英特爾 Xe HPG Arc Alchemist 的正面實(shí)被曝光,不僅擁有 512 EU 版顯卡,還擁有 128EU 的單風(fēng)扇版本。另外,這款顯卡 PCB
Top 主站蜘蛛池模板: 江北区| 徐汇区| 大理市| 双柏县| 平凉市| 苏尼特右旗| 福鼎市| 黑山县| 潍坊市| 隆尧县| 镇巴县| 遂川县| 仲巴县| 涞源县| 敦煌市| 纳雍县| 多伦县| 牡丹江市| 弥渡县| 墨竹工卡县| 乾安县| 乌什县| 博白县| 巴东县| 西华县| 绩溪县| 仁怀市| 安义县| 仙游县| 拜泉县| 兰考县| 新泰市| 饶河县| 肇东市| 家居| 扶余县| 理塘县| 贡嘎县| 甘孜| 镇安县| 新密市|