1,在单个入参的情况下,mybatis不做任何处理,#{参数名} 即可,甚至连参数名都可以不需要,因为只有一个参数,或者使用 Mybatis的内置参数 _parameter。

2,多个入参:
  接口方法定义:public Employee getEmpByIdAndName(Integer id,String name);
       取值:#{id},#{name}
       mybatis抛出异常:org.apache.ibatis.binding.BindingException:Paramter 'id' not found Available parameters are [1,0,param1,param2]
  原因如下:
  Myabtis会特殊处理多个参数,多个参数会被封装成一个Map(key:param1...paramN),或者根据参数索引获取也可以(从0开始),#{param1...paramN}就是从map中获取指定的key的值
 
3,命名参数,明确指定多个参数被封装成Map的可以,在方法入参上使用 @Param("id") 注解。#{id}取值id的值了。

          public Employee getEmpByIdAndName(@Param("id")Integer id,@Param("name")String name);
 
4,POJO,如果多个参数正好是我们业务逻辑的数据模型,可以直接传入POJO,#{属性名},即可取出POJO的属性值了。

          public Employee getEmpByIdAndName(Employee emp);
 
5,Map<String,Object>,如果多个参数不是业务逻辑的数据模型,没有对应的pojo,为了方便,可以传入一个Map。#{key},取出Map中对应的值。

          public Employee getEmpByIdAndName(Map<String,Object> map);
 
6,TO,如果多个参数不是业务逻辑的数据模型,但是要经常使用(比如分页对象),推荐编写一个TO(Transfer Object)数据传输对象。
 
===============================入参为集合====================================
public Employee getEmp(@Param("id")Integer id,String lastName);
     取值:id===>#{id/param1}     lastName=#{param2}
 
public Employee getEmp(Integer id,@Param("e")Employee emp);
     取值:id===>#{param1}     lastName=#{param2.lastName/e.lastName}
 
###特别注意,如果单个入参的类型是为集合类型,也会特殊处理,也是把传入的List或数组封装在Map中key:Collection(collection),如果是List还可以使用这个key(list),如果是数组key为array
public Employee getEmpId(List<Integer> ids);
     取值:取出第一个id的值。#{list[0]}
 
============================================================================================================
Mybatis参数值的获取
  #{}:可以获取Map中的值或者POJO对象属性的值;
  ${}:取值效果同上,但是有区别:
    1,#{}是以预编译的形式,将参数设置到SQL语句中;相当于使用原生的PreparedStatement;(防止SQL注入
    2,${}是以拼接字符串的形式,将参数直接拼接在SQL语句中;(会有安全隐患)
  大多数情况下,都应该去使用#{}取值;
  比如分表:按照年份分表拆分,一年一张财务表。
  select * from ${year}_工资表,表名是没有办法预编译的
  select * from emp order by ${name} ${age},排序也不支持占位符
 
  

  #{}:更为丰富的用法,可以指定参数的类型,类型如下:
    1,javaType,jdbcType,mode(存储过程),numericScale,
               2,resultMap,typeHandler,jdbcTypeName,expression(未来准备支持的功能)
 
    jdbcType通常需要在某种特定的条件下被设置:
      1,在数据为null的时候,有些数据库可能不能识别Mybatis对null的默认处理,比如Oralce环境下会报错。
      2,JdbcType OTHER 无效类型:因为Mybatis对所有的null都映射的是原生Jdbc的OTHER类型,Oracle不能正确处理。(参见 org.apache.ibatis.type.JdbcType 枚举类)
      3,Oracle环境下应该这样取值:#{email,jdbcType=NULL}
    由于Mybatis的全局配置中,jdbcTypeForNull=OTHER,Oracle不支持,直接更改全局配置 jdbcTypeForNull=NULL 。(Settings标签下配置)
 
 
===============================结合源码,查看Mybatis如何处理入参====================================
1,首先我们的Mapper接口对象是一个代理对象(org.apache.ibatis.binding.MapperProxy<T>,它实现了java提供InvocationHandler接口)
  
 
2,被调用的Mapper代理对象的方法,被抽象成为 org.apache.ibatis.binding.MapperMethod 类型的对象,执行其 execute() 方法。它会判断方法的是insert,update,delete还是select。
  
 
3,最后调用MapperMethod对象的 convertArgsToSqlCommandParam(args) 方法将入参转换成一个Map。
  

  

     
  ①获取每个标注了 @Param 注解的参数的param值。然后复制给name。
  ②每次解析一个参数,给map中保存一个信息(key:参数索引,value:name的值)。
    name的值:
                标注了@param注解,注解的值。
                没有标注:
                      1,全局配置:useActualParamName(需要jdk 1.8),name=入参参数名。
                      2,name=map.size();相当于元素的索引。
  ③如果入参为null,直接返回null。
       ④如果names只有一个元素,并且没有 @Param 注解。直接names中的一个元素,直接返回。
       ⑤如果names有多个元素或者有 @Param 注解,遍历names,names集合的value作为key;names集合的key又作为取值的参考args[0]:args[1,"tom"],重新放入一个新的Map对象中。
    额外的将一个参数使用新的key:param1...paramN 保存到一个Map对象中。

Mybatis方法入参处理的更多相关文章

  1. HandlerMethodArgumentResolver(一):Controller方法入参自动封装器【享学Spring MVC】

    每篇一句 你的工作效率高,老板会认为你强度不够.你代码bug多,各种生产环境救火,老板会觉得你是团队的核心成员. 前言 在享受Spring MVC带给你便捷的时候,你是否曾经这样疑问过:Control ...

  2. js方法入参或局部变量和全局变量重名,用来赋值全局变量会失败

    今天遇到个bug,最后终于知道原因了,js方法入参和全局变量重名,用入参赋值全局变量失败,就是说方法入参不能和全局变量重名. 现在下面的例子也说明,局部变量和全局变量不可以同名不光是入参,只要同名赋值 ...

  3. Spring Assert(方法入参检测工具类-断言)

    Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回.类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合要求,方法将通过抛出异 ...

  4. Spring AOP项目应用——方法入参校验 & 日志横切

    转载:https://blog.csdn.net/Daybreak1209/article/details/80591566 应用一:方法入参校验 由于系统多个方法入参均对外封装了统一的Dto,其中D ...

  5. 关于spring中Assert的应用(方法入参检测工具类)

    关于spring中Assert的应用(方法入参检测工具类) Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回.类似的,当我们在编写类的方法时,也常常需要对方 ...

  6. frida框架hook参数获取方法入参模板

    python脚本 # -*- coding: utf-8 -*- import logging import frida import sys logging.basicConfig(level=lo ...

  7. eclipse 查看变量或方法在什么地方被调用的快捷键和快速显示方法入参提示信息

    为了用eclipse写代码的时候,不用方向键移动光标,可以设置如下快捷键, Line Up:Alt+i   光标向上 Line Down:Alt+k 光标向下 Line Start:Alt+u  移到 ...

  8. iview组件select之默认展示label,并传空value做方法入参

    要求: 默认查询操作日期在当日的数据:(打开页面时默认选中时间.全部) 后台约定:选定“全部”这个条件,传的值是空"" 综上:使用select选择框的v-model绑定数据,使用: ...

  9. java 反射取得方法入参类型的泛形

    package TestReflectClass; import java.util.List; /** * Created by wangyang on 2016/12/16. */ public ...

随机推荐

  1. Elevate Web Builder for Web Developers(类似于unigui的东西)

    推荐一款pascal 语言的web 开发工具 这几天仔细研究了一款使用Pascal 语言开发web 的工具 具体介绍可以参照这里. 先上几张他开发的页面照.

  2. QToolBar也是QWidget,可以放在QWidget的中间

    可以试着把左边做成一个widget.从上到下依次为:QTextEditQToolBarQTextEdit然后再对她们进行垂直布局(布局是具体需求而定).代码大致如下: TCenterWidget::T ...

  3. 只言片语 - cell 图片复用问题

    一. 今日做项目遇到图片复用问题,返回cell高度相同,由于网络不好出现图片复用,发现问题   Cell 图片加载方法如下: - (void)sd_setImageWithURL:(NSURL *)u ...

  4. 【canvas】blackboard 黑板

    本来想的挺复杂实际操作了一下15分钟完成了,挺简单的. 预览地址:http://dtdxrk.github.io/game/blackboard/index.html 分享一下思路: 1.创建画布 2 ...

  5. ASP.NET Web API 直到我膝盖中了一箭【1】基础篇

    蓦然回首,那些年,我竟然一直很二. 小时候,读武侠小说的时候,看到那些猪脚,常常会产生一种代入感,幻想自己也会遭遇某种奇遇,遇到悬崖跳下去是不是有本“武林秘笈”在等着?长大以后也是一样,多少人梦着醒着 ...

  6. jmeter报告分析工具

    一直以来做性能测试都是用jmeter和LR,当然还有一些自己写测试脚本,LR不用说,分析结果那个组件杠杠的!但是jmeter毕竟是开源的,所以分析查看结果不像LR那样自带图形神马的,虽然可以自己写脚本 ...

  7. Spring之bean生命始末

    可以为Bean定制初始化后的生命行为,也可以为Bean定制销毁前的生命行为.举例:ba06包.首先,这些方法需要在Bean类中事先定义好:是方法名随意的public void方法. 其次,在配置文件的 ...

  8. Mybatis_two

    SqlMapConfig.xml配置文件 SqlMapConfig.xml中配置的内容和顺序如下: properties(属性) settings(全局配置参数) typeAliases(类型别名) ...

  9. 教妹子用IDEA创建web应用,部署到Tomcat服务器

    自从上一篇原创发表之后,粉丝反应热烈.主要分两派,一派关注技术的,觉得看了那么多的公众号文章,终于找到一篇能看懂的了,于是沾沾自喜.另一派是关注妹子的,感叹自己空有一身绝技,公司里却无妹子可教,大喊可 ...

  10. 长春理工大学第十四届程序设计竞赛(重现赛)I

    I.Fate Grand Order 题目链接:https://ac.nowcoder.com/acm/contest/912/I 题目: Fate Grand Order是型月社发行的角色扮演类手机 ...