Mybatis方法入参处理

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对象中。

时间: 2024-08-07 21:44:52

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

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

Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回.类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合要求,方法将通过抛出异常的方式拒绝后续处理.举一个例子:有一个根据文件名获取输入流的方法:InputStream getData(String file),为了使方法能够成功执行,必须保证 file 入参不能为 null 或空白字符,否则根本无须进行后继的处理.这时方法的编写者通常会在方法体的最前面编写一段对入参进行检测

springMVC(3)方法入参灵活绑定

在原生Servlet中,我们通过在doGet和doPost方法绑定web资源访问接口:HttpServletRequest和HttpServletResponse到入参来进一步通过request.getParameter()等方法获取我们的web资源.在SpringMVC中,我们一样可以将HttpServletRequest和HttpServletResponse绑定到入参中使用,但除此之外,SpringMVC还能进一步分析我们处理方法的入参信息,将各类请求资源绑定到我们的方法入参上,并将数据类

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

Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回.类似的,当我们在编写类的方法时,也常常需要对方法入参进行合 法性检查,如果入参不符合要求,方法将通过抛出异常的方式拒绝后续处理.举一个例子:有一个根据文件名获取输入流的方法:InputStream getData(String file),为了使方法能够成功执行,必须保证 file 入参不能为 null 或空白字符,否则根本无须进行后继的处理.这时方法的编写者通常会在方法体的最前面编写一段对入参进行检测

方法入参和返回值介绍

JAVA方法入参和返回类型 方法入参 基础数据类型 引用数据类型 修饰符 返回类型 方法名(参数类型 参数名,参数类型 参数名...){//方法体return} 方法返回类型 return xxx 具体类型 如果不用返回,则方法返回类型上写void 修饰符 void ?方法名(参数类型 参数名,参数类型 参数名...){//?方法体} 例子 1 package study2day;public class Student1 { 2 private int age; 3 public void s

HandlerMethodArgumentResolver(一):Controller方法入参自动封装器(将参数parameter解析为值)【享学Spring MVC】

HandlerMethodArgumentResolver(一):Controller方法入参自动封装器(将参数parameter解析为值)[享学Spring MVC] 原文地址:https://www.cnblogs.com/hfultrastrong/p/12618488.html

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

要求: 默认查询操作日期在当日的数据:(打开页面时默认选中时间.全部) 后台约定:选定“全部”这个条件,传的值是空"" 综上:使用select选择框的v-model绑定数据,使用:value :label 展示默认数据 ,数组和单个字段. 遇到的问题: 直接在data里面定义{value: '',label: '全部'}失败,当下拉点全部的时候,因为value是空,所以选择框里点“全部”时选不上.传值到接口也失败了. 所以,先赋值value为0,给接口包一层,先判断入参值是否为0,若是

Mybatis中传参包There is no getter for property named &#39;XXX&#39; in &#39;class java.lang.String&#39;

一.发现问题 <select id="queryStudentByNum" resultType="student" parameterType="string"> select num,name,phone from student <where> <if test = " num!=null and num!='' "> AND num = #{num} </if> <

Mybatis中传参包There is no getter for property named &#39;roomName&#39; in &#39;class java.lang.String&#39;

一.发现问题 <select id="queryStudentByNum" resultType="student" parameterType="string"> select num,name,phone from student  <where> <if test = " num!=null and num!='' ">AND num = #{num}</if></w

Mybatis 字符串传参异常解析

Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'XXX' in 'class java.lang.String'  解析 异常信息如下: 1.在DAO层,CardMapper.java接口里面 入参加上 @Param("XXX") 2.在cardMapper.xml中 <if test="provCode != null