前段时间换工作,我去了一家中型互联网公司面试Java开发。技术面上来就是一通熟悉的问题,Spring、Redis、线程池,我答得如鱼得水。轮到MyBatis,我信心满满,毕竟项目里天天用。
结果,面试官看着我说:“那我问个简单点的吧——在Mapper中,如何传递多个参数?”
当时我还在想,这还不简单?用逗号传呗!但我话到嘴边又卡住了——等等,MyBatis的Mapper接口里,方法参数能随便传多个吗?
于是,我硬着头皮答:“我用Map传的……”
面试官点头,又接着问:
“除了Map,你还用过什么方式?@Param你用过吗?那多个参数不用注解的时候,你知道默认怎么传进去的吗?”
就这样,三个问题连珠炮,我脸上写满了‘别问了,我回去查一下’。
回去之后,我立刻翻源码、看官网、写 demo,才把这个“基础问题”吃透。今天就来跟大家完整讲讲 MyBatis 中传多个参数的方式,顺带结合源码看看 MyBatis 的底层是怎么处理这些参数的。
面试官问的“多个参数”到底是哪种情况?
先回顾一下背景。在 MyBatis 中,我们通常会写一个 Mapper 接口,比如这样:
问题就来了:MyBatis 的 XML 映射文件里,只能通过 #{} 或 ${} 获取参数,而方法参数是多个,怎么取?
这就是我们今天要深入的点。
使用 @Param 注解
这是最标准、最推荐的方式!MyBatis 提供了 @Param 注解,可以为每个参数起一个别名。
对应 XML 中就能这样写:
这个时候,MyBatis 内部会把所有的参数封装成一个 Map<String, Object>,你定义了 @Param("xxx"),Map 里就会有对应的键值对,方便取值。
优点:
- 清晰明了
- 对应 XML 一目了然
- 不容易出错
注意:如果用的是 Spring + Mapper 接口(不写 XML),配合注解 SQL 时也推荐用 @Param。
使用 Map 传参(适合参数动态、数量不固定)
这个方式我在项目里常用,比如查询条件很多,有时候我就干脆传个 Map:
XML 里可以这样取:
优点:
- 灵活,应对复杂条件查询
- 动态 SQL 编写非常方便
缺点:
- 缺乏类型约束,IDE 无法提示键名拼写错误
- 可读性略差,尤其参数多时
使用 JavaBean 或 DTO 对象传参
这个适用于场景固定、字段比较多时,比如分页查询时统一传一个 QueryDTO:
XML 中直接用 #{name}、#{age} 即可,MyBatis 会通过反射拿字段值。
优点:
- 类型安全、结构清晰
- 可拓展性强
缺点:
- 如果只查一个字段反而略显臃肿
不加 @Param 的多个参数怎么处理?
这个就是面试官的“陷阱题”了!
如果你在 Mapper 方法里直接写多个参数但不加 @Param:
MyBatis 会自动封装成一个 ParamMap,并用 param1, param2, ... paramN 做 key,也就是:
- param1 → name
- param2 → age
所以 XML 里你只能写:
你写 #{name} 是取不到值的!
所以,不写 @Param 也能用,只是你得知道 MyBatis 默认的命名机制。
MyBatis 是如何封装多个参数的?
这是我写完 demo 后去翻源码才发现的“真相”!
MyBatis 最终会把你传入的方法参数,统一转换成一个 ParamMap(继承自 HashMap),你可以理解为:
当你用了 @Param("name"),它会往 map 里放:
如果你没用 @Param,它会用默认名字:、
而这个 map 就是你在 XML 里的 #{} 对象来源!
面试官为什么这么爱问这个问题?
因为它既考察你的基础,又考察你对 MyBatis 源码的理解。
尤其是在大厂社招,很多项目都用 MyBatis + SpringBoot,而参数传递正是常踩的坑!
举个例子:你同事没加 @Param,结果你写了 #{userId} 就报错了,可能花半小时才找出是应该写 #{param1}……
这类 bug 不难,但一出问题就很低级,容易让人怀疑你对 MyBatis 的熟练度。
项目实战中的使用建议
最后总结一下我在项目中的使用经验:
尾声:面试不怕问,就怕懵
说到底,MyBatis 的多个参数传递不复杂,但细节很多。
从 @Param 到默认 param1 命名,从 Map 到 Bean,其实都是为了让你在 XML 中能准确无误地引用参数。
那次面试之后我深有体会:
“看起来很基础的题,背后往往藏着功力。”
所以,如果你也在准备面试,不妨把这几个参数传递方式都敲一遍,再翻一翻源码,会让你对 MyBatis 的理解更上一层楼。
下次遇到“如何传多个参数”这个问题,你就可以微笑着反问一句:
“您是想听注解方式,还是源码解析?”
END
如果你觉得这篇文章对你有帮助,欢迎【点赞】【转发】和【在看】,支持我这个努力写作的程序员小米~
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
我们下次技术分享,再见!