关键词: mybatis、foreach、foreach context scope、MyBatis3.4.5、BindingException

背景:
随着团队开发人数越来越多,项目迭代越来越久,加上一些半吊子开发的盲目自信,项目如果不够健壮,就会出现莫名其妙的问题,甚至让测试团队对某些开发一瞬间丧失全部信任。

起因是团队有150多个服务的分布式微服务项目,服务之间有RPC调用关系,也有公共组件库,基础类库的交叉引用关系,甚至部分服务提供门面接口,通过maven jar将接口抽象给其他服务提供者使用,自身只实现接口,作为RPC提供者,提供数据。

随着项目迭代,开发引入jar的时候直接去maven 中央仓库搜索坐标,也不关心跟项目中其他依赖的版本对照关系,直接将坐标引入pom.xml中, 由于服务之间有公共jar的相互依赖,公共jar会将一些依赖传递过去,携带到服务依赖中,久而久之,就会造成依赖冲突,甚至出现幻影依赖,知道某个成员用到了介于两个版本之间的API时,问题爆发。

项目中有这么一段远古 mybatis xml代码
image.png

在这段代码中,list的每一批数据,每批数据的plan_id属性都是相同的,plan_idid是一对多的关系

在mybatis 3.4.5之前,这段代码的写法“恰好”没有问题,因为foreach标签中的item作用域是全局,#{item.plan_id, jdbcType=BIGINT}刚好取到了循环id时的最后一个item

由于项目依赖冲突,纠正mybatis依赖

  1. 按照Spring boot版本找mybatis-spring-boot-starter
  2. 找到mybatis-spring-boot-starter中依赖的spring-boot-starter的版本>=当前项目的spring-boot-starter的版本,注意不能跨大版本,例如spring-boot-starter 2.1.x都可以,小版本无影响
  3. 此时mybatis-spring-boot-starter中传递的mybatis版本就是最佳的

由于正好最合适的mybatis版本是3.4.6,之前的版本一直是3.4.2,遇到了这个问题,报错:
BindingException: Parameter: 'xxx' not found. Available parameters are [list, param1]

由于我本人非常熟悉MyBatis的源码,这个问题一下就猜到,直接将根本原因找出来

最后,告诫各位写代码时遵循以下几点

  1. 写代码一定要写健壮性强的代码,不给自己留坑,也不给别人挖坑
  2. 每写一行代码,一个函数,一个类,做到无IDE警告,必要时使用@SuppressWarnings压制
  3. 调用三方库、三方组件时多思考,多看源码,不写有歧义的代码
  4. 自己封装函数前,先考虑有没有可靠库可以使用,例如guavacommons-lang

witt
588 声望462 粉丝

一位爱好计算机运维,喜欢折腾软件,不爱写代码的准Java开发程序员。