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. 如何作为一个优秀的ERP实施顾问

    原文地址:如何作为一个优秀的ERP实施顾问作者:天思软件 作一个优秀的ERP实施顾问无论是天思.金蝶,用友,还是其他业务软件.实施顾问的发展道路都差不多. 1.初级实施顾问,中级实施顾问,高级实施顾问 ...

  2. Change Default Route

    route delete 0.0.0.0route add 0.0.0.0 mask 0.0.0.0 10.226.4.14

  3. Bamboo 0.2.11 发布,HAProxy 自动配置

    Bamboo 0.2.11 发布,此版本更新内容如下: 新特性 提供更多的模板字符串函数:strings.Split,  strings.Join,strings.Replace, strings.T ...

  4. 所有W版本的函数都在wchar.h文件(_wfopen),和stdlib.h文件(wcstombs),和stdio.h文件(vwprintf)

    C:\Qt\Qt5.6.2\Tools\mingw492_32\i686-w64-mingw32\include\wchar.h C:\Qt\Qt5.6.2\Tools\mingw492_32\i68 ...

  5. TStringGrid多选的复制与拷贝

    uses Clipbrd; function StringGridSelectText(mStringGrid: TStringGrid): string; var   I, J: Integer; ...

  6. SpringCloud微服务架构升级总结

    一.背景 1.1 应用系统的架构历史 1.2 什么是微服务? 起源:微服务的概念源于 2014 年 3 月 Martin Fowler 所写的一篇文章“Microservices”.文中内容提到:微服 ...

  7. MAC电脑修改Terminal以及vim高亮显示

    1. Terminal高亮显示 编辑~/.bash_profile文件,在末尾增加两行: export CLICOLOR= export LSCOLORS=exfxcxdxcxegedabagacad ...

  8. Storm 学习之路(五)—— Storm编程模型详解

    一.简介 下图为Strom的运行流程图,在开发Storm流处理程序时,我们需要采用内置或自定义实现spout(数据源)和bolt(处理单元),并通过TopologyBuilder将它们之间进行关联,形 ...

  9. HBase 学习之路(六)——HBase Java API 的基本使用

    一.简述 截至到目前(2019.04),HBase 有两个主要的版本,分别是1.x 和 2.x ,两个版本的Java API有所不同,1.x 中某些方法在2.x中被标识为@deprecated过时.所 ...

  10. Kafka 学习之路(三)—— Kafka生产者详解

    一.生产者发送消息的过程 首先介绍一下Kafka生产者发送消息的过程: Kafka会将发送消息包装为ProducerRecord对象, ProducerRecord对象包含了目标主题和要发送的内容,同 ...