關鍵詞: mybatis、foreach、foreach context scope、MyBatis3.4.5、BindingException
背景:
隨着團隊開發人數越來越多,項目迭代越來越久,加上一些半吊子開發的盲目自信,項目如果不夠健壯,就會出現莫名其妙的問題,甚至讓測試團隊對某些開發一瞬間喪失全部信任。
起因是團隊有150多個服務的分佈式微服務項目,服務之間有RPC調用關係,也有公共組件庫,基礎類庫的交叉引用關係,甚至部分服務提供門面接口,通過maven jar將接口抽象給其他服務提供者使用,自身只實現接口,作為RPC提供者,提供數據。
隨着項目迭代,開發引入jar的時候直接去maven 中央倉庫搜索座標,也不關心跟項目中其他依賴的版本對照關係,直接將座標引入pom.xml中, 由於服務之間有公共jar的相互依賴,公共jar會將一些依賴傳遞過去,攜帶到服務依賴中,久而久之,就會造成依賴衝突,甚至出現幻影依賴,知道某個成員用到了介於兩個版本之間的API時,問題爆發。
項目中有這麼一段遠古 mybatis xml代碼
在這段代碼中,list的每一批數據,每批數據的plan_id屬性都是相同的,plan_id與id是一對多的關係
在mybatis 3.4.5之前,這段代碼的寫法“恰好”沒有問題,因為foreach標籤中的item作用域是全局,#{item.plan_id, jdbcType=BIGINT}剛好取到了循環id時的最後一個item
由於項目依賴衝突,糾正mybatis依賴
- 按照
Spring boot版本找mybatis-spring-boot-starter - 找到
mybatis-spring-boot-starter中依賴的spring-boot-starter的版本>=當前項目的spring-boot-starter的版本,注意不能跨大版本,例如spring-boot-starter 2.1.x都可以,小版本無影響 - 此時
mybatis-spring-boot-starter中傳遞的mybatis版本就是最佳的
由於正好最合適的mybatis版本是3.4.6,之前的版本一直是3.4.2,遇到了這個問題,報錯:
BindingException: Parameter: 'xxx' not found. Available parameters are [list, param1]
由於我本人非常熟悉MyBatis的源碼,這個問題一下就猜到,直接將根本原因找出來
- MyBatis bug issue
- MyBatis release v3.4.5
最後,告誡各位寫代碼時遵循以下幾點
- 寫代碼一定要寫健壯性強的代碼,不給自己留坑,也不給別人挖坑
- 每寫一行代碼,一個函數,一個類,做到無IDE警告,必要時使用
@SuppressWarnings壓制 - 調用三方庫、三方組件時多思考,多看源碼,不寫有歧義的代碼
- 自己封裝函數前,先考慮有沒有可靠庫可以使用,例如
guava、commons-lang等