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. Android零基础入门第73节:Activity初入门,创建和配置如此简单

    Activity是Android应用的重要组成单元之一,也是Android应用最常见的组件之一.前面看到的示例通常都只包含一个Activity或一个AppCompatActivity,但在实际应用中这 ...

  2. Jquery 插件开发公开属性顺序的影响.

    如下代码拷贝能正常运行. (function ($) { $.fn.DemoPlugin = function (options) { var opts; opts = $.extend({}, $. ...

  3. 设置qt插件路径

    1.在Qt中使用 WebKit 浏览器核心 使用 QtWebKit 需要在工程文件(*.pro)中加入: QT +=webkitQT += network 2.QtWebKit的flash支持 QtW ...

  4. TextBox的Enable和ReadOnly属性的限制

    在以前的ASP.NET 1.x版本中,设置为ReadOnly的TextBox控件在客户端更改了值后,在服务器端仍然可以得到修改后的值,但在ASP.NET 2.0中,这种做法已经限制.这是为了提高应用程 ...

  5. Hadoop集群(第5期)SecureCRT使用

    1.SecureCRT简介   SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议.SecureCRT是一款用于连接运行包括Windows. ...

  6. 用node.js(socket.io)实现数据实时推送

    在做商品拍卖的时候,要求在商品的拍卖页面需要实时的更新当前商品的最高价格.实现的方式有很多,比如: 1.setInterval每隔n秒去异步拉取数据(缺点:更新不够实时) 2. AJAX轮询方式方式推 ...

  7. RocketMQ(1)-架构原理

    RocketMQ(1)-架构原理 RocketMQ是阿里开源的分布式消息中间件,跟其它中间件相比,RocketMQ的特点是纯JAVA实现:集群和HA实现相对简单:在发生宕机和其它故障时消息丢失率更低. ...

  8. 前端视频转码flv->swf

    在项目中本来是要用<video>标签插入视频,但此标签不支持flv格式,上网也是搜了很多,试了很久才成功(其他格式不是很清楚你们可以尝试看看) 所用技术 flach (Flvplayer. ...

  9. Spring Boot:集成Druid数据源

    综合概述 数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个:释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据 ...

  10. Android开发需要了解的 IM 知识

    引言 即便在通讯如此发达的今天,IM 也依然是诸多场景下非常重要的基础能力.因此做为 一名 Android 开发,不可避免的会遇到一些IM 相关的需求或问题.本文以一个Android开发的角度来讲述I ...