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零基础入门第66节:RecyclerView点击事件处理

    前面两期学习了RecyclerView的简单使用,并为其item添加了分割线.在实际运用中,无论是List还是Grid效果,基本都会伴随着一些点击操作,那么本期就来一起学习RecyclerView的点 ...

  2. Creating a Linux Daemon (service) in Delphi

    With the introduction of the Linux target for Delphi, a wide range of possibilities are opened up to ...

  3. Windows完成端口与猪肉佬

    首先应该说明的是,我也是第一次使用完成端口.虽然以前偶尔在网上看到完成端口的文章和代码,但真正自己动手写还是第一次,不过我这个人有个特点就是大胆,例如没有写那个界面编程系列前,其实我甚至不知道原来一个 ...

  4. Windows环境下使用Node.js

    作者:短工邦技术部 - 陈文哲 Parse用的就是Node.js,所以我们要先了解什么是Node.js,以及做一些简单的操作. Node.js 的主要思路是:使用非阻塞的,事件驱动的 I/O 操作来保 ...

  5. 解析 Qt 字库移植并能显示中文 (下篇)

    原文http://mobile.51cto.com/symbian-272563.htm 本文介绍的是Qt 字库移植并能显示中文,需要的字体库文件,一般是多个.具体移植那一个,看你使用的字库是什么了, ...

  6. 从此Redis是路人

    从此Redis是路人 序言:Redis(Remote DIctionary Server)作为一个开源/C实现/高性能/基于内存的key-value存储系统,相信做Java的小伙伴都不会陌生.Redi ...

  7. 设置windows服务依赖项

    场景还原:python2.7开发的项目,制作成了windows服务,随系统启动.系统重启后发现服务未能自动启动,检查事件查看器日志发现服务先于Mysql数据库服务启动,由于服务中必须对MySQL进行访 ...

  8. sql关联查询—将一个表的查询结果作为新表进行查询操作

    例题:#  各个部门中 最高工资中最低的那个部门的 最低工资是多少? 先考虑取得各个部门最高工资 SELECT MAX(salary) AS max_salary,e.`department_id` ...

  9. Python|网页转PDF,PDF转图片爬取校园课表~

    import pdfkit import requests from bs4 import BeautifulSoup from PIL import Image from pdf2image imp ...

  10. spring 5.x 系列第3篇 —— spring AOP (xml配置方式)

    文章目录 一.说明 1.1 项目结构说明 1.2 依赖说明 二.spring aop 2.1 创建待切入接口及其实现类 2.2 创建自定义切面类 2.3 配置切面 2.4 测试切面 附: 关于切面表达 ...