一、前言

Mybatis在使用Mapper接口进行编程时,底层采用了动态代理机制,表面上是调用的Mapper接口,而实际上是通过动态代理调用的SqlSession的对应方法,其最终会获得一个代理了Mapper接口的MapperProxy对象。MapperProxy对象在调用Mapper接口方法时会把传递的参数做一个转换,然后把转换后的参数作为入参传递给SqlSession对应的操作方法(如selectOne、insert等)。转换过程可以参考MapperMethod的execute()方法实现。简单来说是以下规则:
♦单个参数:可以接受基本类型,对象类型,集合类型的值。这种情况MyBatis可直接使用这个参数,不需要经过任何处理。
♦多个参数:任意多个参数,都会被MyBatis重新包装成一个Map传入。Map的key是param1,param2,0,1…,值就是参数的值。
♦命名参数:为参数使用@Param起一个名字,MyBatis就会将这些参数封装进map中,key就是我们自己指定的名字。
♦POJO:当这些参数属于我们业务POJO时,我们直接传递POJO。
♦Map:我们也可以封装多个参数为map,直接传递。

本节我们将介绍一下,MyBatis是如何处理单个参数和多个参数的?

二、案例

在MySQL下新建数据库表t_user,并插入一条数据

CREATE TABLE t_user (id int(10) NOT NULL AUTO_INCREMENT,loginId varchar(20) DEFAULT NULL,userName varchar(100) DEFAULT NULL,role varchar(255) DEFAULT NULL,note varchar(255) DEFAULT NULL,PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;INSERT INTO t_user(loginId,userName,role,note) VALUES ('queen', '奎恩', '海贼王副把手', '专门负责提鞋的。。。');

编写UserMapper.xml文件

<select id="findUserById" resultType="com.queen.mybatis.bean.User">select id, loginId, userName, role, note from t_user where id = #{id}
</select>

编写MyBatisTest.java测试类,新增测试方法testOneParam

@Test
public void testOneParam() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();SqlSession openSession = sqlSessionFactory.openSession();try {UserMapper mapper = openSession.getMapper(UserMapper.class);User user = mapper.findUserById(1);System.out.println(user);} finally {openSession.close();}
}

运行测试,控制台打印如下:

2017-08-04 23:07:28,536 [main] [com.queen.mybatis.mapper.UserMapper.findUserById]-[DEBUG] ==>  Preparing: select id, loginId, userName, role, note from t_user where id = ?
2017-08-04 23:07:28,589 [main] [com.queen.mybatis.mapper.UserMapper.findUserById]-[DEBUG] ==> Parameters: 1(Integer)
2017-08-04 23:07:28,626 [main] [com.queen.mybatis.mapper.UserMapper.findUserById]-[DEBUG] <==      Total: 1
User [id=1, loginId=queen, userName=奎恩, role=海贼王副把手, note=专门负责提鞋的。。。]

其实,当你传递单个参数时,#{xxx}里面这个“xxx”无论你写什么都一样,因为只有一个参数,你可以试着修改UserMapper.xml文件中where id = #{idabcd},如下:

<select id="findUserById" resultType="com.queen.mybatis.bean.User">select id, loginId, userName, role, note from t_user where id = #{idabcd}
</select>

测试查询,同样可以查出数据。单个参数下,MyBatis不会做任何处理。那如果是多个参数呢?

同样是查询User信息,但是我们以ID和userName两个参数去查询,在UserMapper.java中新增查询方法,如下:

/**
* 根据ID和用户名查找用户
* @param id
* @param userName
* @return*/
public User findUserByIdAndUserName(int id, String userName);

在UserMapper.xnl增加配置如下

<select id="findUserByIdAndUserName" resultType="com.queen.mybatis.bean.User">select id, loginId, userName, role, note from t_user where id = #{id} and userName=#{userName}
</select>

编写MyBatisTest.java测试类,新增测试方法testTwoParam

@Test
public void testTwoParam() throws IOException {SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();SqlSession openSession = sqlSessionFactory.openSession();try {UserMapper mapper = openSession.getMapper(UserMapper.class);User user = mapper.findUserByIdAndUserName(1, "奎恩");System.out.println(user);} finally {openSession.close();}
}

大家想一想,当我们传递两个参数的时候,这种方式编写能成功吗?我们先试着运行一下testTwoParam方法,看啊看控制台打印何种结果?运行结果如下:

org.apache.ibatis.exceptions.PersistenceException:
### Error querying database.  Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [1, 0, param1, param2]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [1, 0, param1, param2]at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:26)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:111)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:66)at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:68)at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)at com.sun.proxy.$Proxy2.findUserByIdAndUserName(Unknown Source)at com.queen.mybatis.MyBatisTest.testTwoParam(MyBatisTest.java:46)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:606)

很不凑巧,大失所望,控制台报错:“Parameter ‘id’ not found. Available parameters are [1, 0, param1, param2]”,说绑定异常,参数ID没有找到,有效的参数是[1, 0, param1, param2]。这是什么意思呢?

其实MyBatis在处理多个参数的时候,MyBatis会做特殊处理,多个参数会被封装成一个map,map中是这么存值的

map.put("param1","传入的参数值1");
map.put("param2","传入的参数值2");
map.put("param3","传入的参数值3");...
map.put("paramN","传入的参数值N");

#{}就是从map中获取指定的key值。

这个时候我们要将UserMapper.xml中查询方法做如下修改:

<select id="findUserByIdAndUserName" resultType="com.queen.mybatis.bean.User"><!--select id, loginId, userName, role, note from t_user where id = #{id} and userName=#{userName} -->select id, loginId, userName, role, note from t_user where id = #{param1} and userName=#{param2}
</select>

或者

<select id="findUserByIdAndUserName" resultType="com.queen.mybatis.bean.User"><!--select id, loginId, userName, role, note from t_user where id = #{id} and userName=#{userName} --><!--select id, loginId, userName, role, note from t_user where id = #{param1} and userName=#{param2} -->select id, loginId, userName, role, note from t_user where id = #{0} and userName=#{1}
</select>

测试查询,控制台打印如下:

2017-08-04 23:41:38,401 [main] [com.queen.mybatis.mapper.UserMapper.findUserByIdAndUserName]-[DEBUG] ==>  Preparing: select id, loginId, userName, role, note from t_user where id = ? and userName=?
2017-08-04 23:41:38,466 [main] [com.queen.mybatis.mapper.UserMapper.findUserByIdAndUserName]-[DEBUG] ==> Parameters: 1(Integer), 奎恩(String)
2017-08-04 23:41:38,503 [main] [com.queen.mybatis.mapper.UserMapper.findUserByIdAndUserName]-[DEBUG] <==      Total: 1
User [id=1, loginId=queen, userName=奎恩, role=海贼王副把手, note=专门负责提鞋的。。。]

虽然这两种方式,都能取到值,但是给人的感觉比较怪怪的,看起来跟我们平时的写法不太一样,按照大家预想where id = #{id} and userName=#{userName} 这种写法方式,是最让人舒服的。为了解决这种方式使用,MyBatis提供了命名参数的方式,在传递参数时,明确指出封装参数时map的key,这样我们在XML中就能使用where id = #{id} and userName=#{userName} 这种写法来传递参数了。

=======欢迎大家拍砖,小手一抖,多多点赞哟!=======

版权声明:本文为博主原创文章,允许转载,但转载必须标明出处。

老司机学习MyBatis之如何处理参数(单个参数或者多个参数)相关推荐

  1. 老司机学习MyBatis之如何通过select返回Map

    From: https://blog.csdn.net/Gaomb_1990/article/details/80638177 一.案例 当要查询的结果是一个Map的时候,这里分为两种情况: ①返回单 ...

  2. 老司机学习MyBatis之mappers如何配置映射注册

    一.前言 定义SQL映射语句,首先我们要告诉MyBatis去哪里找到这些语句,Java在自动查找这方面没有提供一个很好的方法,所以最佳方式是告诉MyBatis到哪里去查找映射文件,你可以使用相对路径的 ...

  3. 老司机学习MyBatis之逆向工程MGB的简单使用

    一.前言 MyBatis Generator简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,以及bean类.支持基本的增删改查,以及QBC风 ...

  4. AI向程序员老司机学习:从眼神的变化中寻找bug

    晓查 发自 凹非寺  量子位 报道 | 公众号 QbitAI 用AI找bug这件事,有人尝试过,结果翻车了.美国网站Yelp的程序员们试图让AI帮自己找bug,岂料AI却删库跑路,最后只能用回滚的办法 ...

  5. stm32 web 参数_老司机们都是怎么学习STM32的?

    单片机用处这么广,尤其是STM32,这么火!如何快速上手学习呢? "不要去学STM32".我不是说STM32不好,而是这种为了学习单片机而去学习单片机的思路不对.你问,如何系统地入 ...

  6. 我学习 Java 的历程和体会(写给新手看,欢迎老司机批评和建议,持续更新中)

    我学习 Java 的历程和体会(写给新手看,欢迎老司机批评和建议,持续更新中) 最初写这篇文章的时候,是在今年的 9 月中旬.今天,我想再写写这将近两个多月以来的感受. 在今年的 10 月我来到北京求 ...

  7. 老司机们都是怎么学习STM32的?

    单片机用处这么广,尤其是STM32,这么火!如何快速上手学习呢? "不要去学STM32".我不是说STM32不好,而是这种为了学习单片机而去学习单片机的思路不对. 你问,如何系统地 ...

  8. proteus里面没有stm32怎么办_STM32难不难,如何学习?这几点老司机建议,你得好好收藏!...

    单片机用处这么广,尤其是STM32,这么火!如何快速上手学习呢? "不要去学STM32".我不是说STM32不好,而是这种为了学习单片机而去学习单片机的思路不对. 你问,如何系统地 ...

  9. 显卡的指标有哪些方面_纯干货!显卡购买重要参数:老司机勿入

    1你是N饭还是A饭? 近年来随着电竞游戏及单机大作的加速发布,游戏对显卡性能的需求越来越高,而最新的GTX 10系新品与RX VEGA系相较于上一代产品性能也有了质的提升,这让很多游戏玩家有了升级显卡 ...

最新文章

  1. 深度学习模型训练过程
  2. WSAStartup函数
  3. 过年(2015)读书笔记
  4. 图书管理系统(大一C语言大作业 包含主要结构体,文件操作, 如数据的修改 查询 删除等)
  5. URLDecoder与URLDecoder的简单了解
  6. linux glibc升级
  7. 人脸识别:AI产品经理需要了解的CV通识
  8. 云计算现在好就业吗?薪资怎么样?
  9. 2021-10-26 2021年B站1024安全攻防题第五题(安卓逆向)
  10. 2021自学考试计算机应用基础,2021年高等教育自学考试计算机应用基础试题及答案.doc...
  11. 设计模式(二)-软件开发过程中需要遵循的设计原则
  12. 关于临时HY学长被安排拉二分题不想翻译找到DYM学长这件事(三)
  13. 点与直线位置关系,叉乘
  14. FVCOM 环境基础配置(1) intel编译器 下载与安装
  15. 安装ps显示计算机丢失adobe,win7系统安装PS显示检查许可证所需的adobe application manager丢失或损坏的解决方法...
  16. 知识付费直播使用https方法
  17. python中os.path.join()的循环用法_python中使用os.path.join()
  18. 菊风云 | 音视频社交崛起的背后
  19. 【小组作业】电影院管理系统
  20. 全球化安全生产 质量保障体系建设探索

热门文章

  1. 一键安装,双击运行——Java安装程序制作
  2. Django框架全面讲解
  3. 这次我们又引领了潮流——容器存储双活
  4. servu文件服务器备份,用SERV_U建立文件备份系统
  5. 初中教师计算机培训方案,学校教师信息技术应用能力提升培训方案
  6. elementui表格中使用表格数据(微信头像地址)显示图片
  7. python爬取空气质量_python爬取全国空气质量信息
  8. 人形迎宾机器人眨眼动嘴_人形教育表演机器人
  9. bugfree使用手册
  10. FPGA 可编程门阵列LCMXO2-1200HC-4MG132C概述