zoukankan      html  css  js  c++  java
  • 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对象中。
  • 相关阅读:
    接口测试总结
    在 github 上获取源码
    推荐一个css帮助手册的版本 同时提供chm和在线
    由csdn开源项目评选中闹出刷票问题想到投票程序的设计
    由一个园友因为上传漏洞导致网站被攻破而得到的教训
    让 SVN (TortoiseSVN)提交时忽略bin和obj目录
    未能进入中断模式,原因如下:源文件“XXXXXX”不属于正在调试的项目。
    未能加载文件或程序集“XXXXX”或它的某一个依赖项。试图加载格式不正确的程序。
    .Net AppDomain.CurrentDomain.AppendPrivatePath(@"Libs");
    C# Remoting的一个简单例子
  • 原文地址:https://www.cnblogs.com/startcaft/p/7462440.html
Copyright © 2011-2022 走看看