zoukankan      html  css  js  c++  java
  • myBatis参数处理 myBatis佟刚课程笔记

    单个参数:myBatis不会做特殊处理
    #{参数名}: 取出参数值

    多个参数: myBatis会做特殊处理
    多个参数会被封装成一个MAP
    key:param1 param2.... param10,或者参数的索引也可以
    value: 使我们传入的参数的值
    异常:
    org.apache.ibatis.binding.BindingException:
    Parameter 'id' not found.
    Available parameters are [arg1, arg0, param1, param2]
    操作:
    public Employee getEmpByIdAndLastName(String id, String lastName);
    例如:
    <select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.bean.Employee">
    select * from EMPLOYEE where EMPLOYEE_ID = #{param1} and LAST_NAME = #{param2}
    </select>

    命名参数:明确指定封装参数时map的key
    public Employee getEmpByIdAndLastName(@Param("id")String id, @Param("lastName") String lastName);
    多个参数会被封装成一个map
    key,使用@Param注解指定的值
    value,参数值
    #{参数名}
    <select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.bean.Employee">
    select * from EMPLOYEE where EMPLOYEE_ID = #{id} and LAST_NAME = #{lastName}
    </select>
    也就是分两步,首先在函数中注解参数,其次在编写SQL语句的时候,使用参数

    POJO: Plain Ordinary Java Object 简单的Java对象
    如果多个参数正好是业务逻辑的数据模型,我们就可以直接传入POJO
    #{属性名}: 取出传入的POJO属性值

    如果多个参数不是业务逻辑中的参数,没有对应的POJO,为了方便,我们也可以传入Map
    1、public Employee getEmpByMap(Map<String, Object> map);
    #{key}:取出map对应的值
    2、Map<String, Object> map = new HashMap<>();
    map.put("id","1");
    map.put("lastName", "SNOOPY");
    Employee employee = mapper.getEmpByMap(map);
    3、 <select id="getEmpByMap" resultType="com.atguigu.mybatis.bean.Employee">
    select * from EMPLOYEE where EMPLOYEE_ID = #{id} and LAST_NAME = #{lastName}
    </select>

    如果多个参数不是业务逻辑中的数据,但是经常要使用,使用MAP就消耗了太多资源,推荐编写一个TO(Transfer Object)数据传输对象
    Page{
    int index;
    int size;
    }

    =====================思考==================================
    public Employee getEmp(@Prarm("id") Integer id, String lastName);
    取值:id #{id|param1} lastName #{param2}
    public Employee getEmp(Integer id, @Param("e") Employee employee);
    取值:id #{param1} lastName #{param2.lastName|e.lastName}

    ### 特别注意 如果是Collection(List Set ...)或者是数组,也会特殊处理
    特殊处理的方法也是把传入的List封装到Map中
    key: Collection(collection), key(list), Array(array)
    public Employee getEmpById(List<Integer> IDS);
    取值:取出第一个id #{list[0]}


    ======================结合源码,myBatis如何处理参数===========================
    总结:参数多时会封装map,为了不混乱,我们可以使用@Param来指定封装时的key,
    #{key}就可以取出map中的值
    /**
    * <p>
    * A single non-special parameter is returned without a name.<br />
    * Multiple parameters are named using the naming rule.<br />
    * In addition to the default names, this method also adds the generic names (param1, param2,
    * ...).
    * </p>
    */
    (@Param("id")String id, @Param("lastName") String lastName);
    ParamNameResolver:解析参数名的函数,并且封装为MAP
    // 1、names:{0 = id, 1 = lastName}:构造器的时候就确定好了
    确定流程:
    1、获取每个标了param注解的参数@Param的值:id, lastName;赋值给name;
    2、每次解析一个参数给map中保存信息:(key:参数索引,value:name的值}
    name的值:
    标注了Param注解:注解的值
    没有标注:
    1.全局配置了:useActualParamName(jdk1.8):name=参数名
    2.name = map.size():相当于当前元素的索引
    map names==> {0 = id, 1 = lastName, 2= 2}

    args["1", "SNOOPY", "Hello"]:

    public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();

    //1、如果参数为null直接返回
    if (args == null || paramCount == 0) {
    return null;

    //2、如果只有一个元素并且没有Param注解,args[0]:单个参数直接返回
    } else if (!hasParamAnnotation && paramCount == 1) {
    return args[names.firstKey()];
    //3、多个元素或者有Param标注

    } else {
    final Map<String, Object> param = new ParamMap<Object>();
    int i = 0;

    // 4、遍历names集合,names:{0 = id, 1 = lastName, 2 = 2}
    for (Map.Entry<Integer, String> entry : names.entrySet()) {

    //建了另外一个map:param
    //names的value值作为param的key,names集合的key又作为取值的参考args[0]:args["1", "SNOOPY"]
    //{id=arg[0]:"1", lastName=arg[1]:"SNOPPY", 2=arg[2]:"Hello"}
    param.put(entry.getValue(), args[entry.getKey()]);
    // add generic param names (param1, param2, ...)
    // 额外的将每一个参数也保存到MAP中,使用新的key: param1 param2 ...
    // 效果:有Param注解,可以#{指定的key},或者#{param1}
    final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
    // ensure not to overwrite parameter named with @Param
    if (!names.containsValue(genericParamName)) {
    param.put(genericParamName, args[entry.getKey()]);
    }
    i++;
    }
    return param;
    }
    }
    }

    #{}更丰富的用法
    规定参数的一些规则:
    javaType, jdbcType, mode(存储过程), numericScale, resultMap,
    typeHandler, jdbcTypeName, expression(未来准备支持的功能)

    jdbcType通常需要在某种特定条件下被设置,
    在我们数据为null的时候,有些数据库可能不能识别myBatis对null的默认处理,比如Oracle(报错)
    jdbcType OTHER:无效的类型
    由于全局配置文件中,jdbcTypeForNull=OTHER; Oracle不支持;两种方法都行
    解决方法:1、#{email, jdbcType = NULL};
    2、jdbcTypeForNull = NULL;(在全局配置文件中修改)
    <setting name="mapUnderscoreToCamelCase" value="true"/>








    单个参数:myBatis不会做特殊处理
    #{参数名}: 取出参数值

    多个参数: myBatis会做特殊处理
    多个参数会被封装成一个MAP
    key:param1 param2.... param10,或者参数的索引也可以
    value: 使我们传入的参数的值
    异常:
    org.apache.ibatis.binding.BindingException:
    Parameter 'id' not found.
    Available parameters are [arg1, arg0, param1, param2]
    操作:
    public Employee getEmpByIdAndLastName(String id, String lastName);
    例如:
    <select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.bean.Employee">
    select * from EMPLOYEE where EMPLOYEE_ID = #{param1} and LAST_NAME = #{param2}
    </select>

    命名参数:明确指定封装参数时map的key
    public Employee getEmpByIdAndLastName(@Param("id")String id, @Param("lastName") String lastName);
    多个参数会被封装成一个map
    key,使用@Param注解指定的值
    value,参数值
    #{参数名}
    <select id="getEmpByIdAndLastName" resultType="com.atguigu.mybatis.bean.Employee">
    select * from EMPLOYEE where EMPLOYEE_ID = #{id} and LAST_NAME = #{lastName}
    </select>
    也就是分两步,首先在函数中注解参数,其次在编写SQL语句的时候,使用参数

    POJO: Plain Ordinary Java Object 简单的Java对象
    如果多个参数正好是业务逻辑的数据模型,我们就可以直接传入POJO
    #{属性名}: 取出传入的POJO属性值

    如果多个参数不是业务逻辑中的参数,没有对应的POJO,为了方便,我们也可以传入Map
    1、public Employee getEmpByMap(Map<String, Object> map);
    #{key}:取出map对应的值
    2、Map<String, Object> map = new HashMap<>();
    map.put("id","1");
    map.put("lastName", "SNOOPY");
    Employee employee = mapper.getEmpByMap(map);
    3、 <select id="getEmpByMap" resultType="com.atguigu.mybatis.bean.Employee">
    select * from EMPLOYEE where EMPLOYEE_ID = #{id} and LAST_NAME = #{lastName}
    </select>

    如果多个参数不是业务逻辑中的数据,但是经常要使用,使用MAP就消耗了太多资源,推荐编写一个TO(Transfer Object)数据传输对象
    Page{
    int index;
    int size;
    }

    =====================思考==================================
    public Employee getEmp(@Prarm("id") Integer id, String lastName);
    取值:id #{id|param1} lastName #{param2}
    public Employee getEmp(Integer id, @Param("e") Employee employee);
    取值:id #{param1} lastName #{param2.lastName|e.lastName}

    ### 特别注意 如果是Collection(List Set ...)或者是数组,也会特殊处理
    特殊处理的方法也是把传入的List封装到Map中
    key: Collection(collection), key(list), Array(array)
    public Employee getEmpById(List<Integer> IDS);
    取值:取出第一个id #{list[0]}


    ======================结合源码,myBatis如何处理参数===========================
    总结:参数多时会封装map,为了不混乱,我们可以使用@Param来指定封装时的key,
    #{key}就可以取出map中的值
    /**
    * <p>
    * A single non-special parameter is returned without a name.<br />
    * Multiple parameters are named using the naming rule.<br />
    * In addition to the default names, this method also adds the generic names (param1, param2,
    * ...).
    * </p>
    */
    (@Param("id")String id, @Param("lastName") String lastName);
    ParamNameResolver:解析参数名的函数,并且封装为MAP
    // 1、names:{0 = id, 1 = lastName}:构造器的时候就确定好了
    确定流程:
    1、获取每个标了param注解的参数@Param的值:id, lastName;赋值给name;
    2、每次解析一个参数给map中保存信息:(key:参数索引,value:name的值}
    name的值:
    标注了Param注解:注解的值
    没有标注:
    1.全局配置了:useActualParamName(jdk1.8):name=参数名
    2.name = map.size():相当于当前元素的索引
    map names==> {0 = id, 1 = lastName, 2= 2}

    args["1", "SNOOPY", "Hello"]:

    public Object getNamedParams(Object[] args) {
    final int paramCount = names.size();

    //1、如果参数为null直接返回
    if (args == null || paramCount == 0) {
    return null;

    //2、如果只有一个元素并且没有Param注解,args[0]:单个参数直接返回
    } else if (!hasParamAnnotation && paramCount == 1) {
    return args[names.firstKey()];
    //3、多个元素或者有Param标注

    } else {
    final Map<String, Object> param = new ParamMap<Object>();
    int i = 0;

    // 4、遍历names集合,names:{0 = id, 1 = lastName, 2 = 2}
    for (Map.Entry<Integer, String> entry : names.entrySet()) {

    //建了另外一个map:param
    //names的value值作为param的key,names集合的key又作为取值的参考args[0]:args["1", "SNOOPY"]
    //{id=arg[0]:"1", lastName=arg[1]:"SNOPPY", 2=arg[2]:"Hello"}
    param.put(entry.getValue(), args[entry.getKey()]);
    // add generic param names (param1, param2, ...)
    // 额外的将每一个参数也保存到MAP中,使用新的key: param1 param2 ...
    // 效果:有Param注解,可以#{指定的key},或者#{param1}
    final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
    // ensure not to overwrite parameter named with @Param
    if (!names.containsValue(genericParamName)) {
    param.put(genericParamName, args[entry.getKey()]);
    }
    i++;
    }
    return param;
    }
    }
    }

    #{}更丰富的用法
    规定参数的一些规则:
    javaType, jdbcType, mode(存储过程), numericScale, resultMap,
    typeHandler, jdbcTypeName, expression(未来准备支持的功能)

    jdbcType通常需要在某种特定条件下被设置,
    在我们数据为null的时候,有些数据库可能不能识别myBatis对null的默认处理,比如Oracle(报错)
    jdbcType OTHER:无效的类型
    由于全局配置文件中,jdbcTypeForNull=OTHER; Oracle不支持;两种方法都行
    解决方法:1、#{email, jdbcType = NULL};
    2、jdbcTypeForNull = NULL;(在全局配置文件中修改)
    <setting name="mapUnderscoreToCamelCase" value="true"/>

































  • 相关阅读:
    Codeforces 877 C. Slava and tanks
    Codeforces 877 D. Olya and Energy Drinks
    2017 10.25 NOIP模拟赛
    2017 国庆湖南 Day1
    UVA 12113 Overlapping Squares
    学大伟业 国庆Day2
    51nod 1629 B君的圆锥
    51nod 1381 硬币游戏
    [JSOI2010]满汉全席
    学大伟业 2017 国庆 Day1
  • 原文地址:https://www.cnblogs.com/zjulanjian/p/9194911.html
Copyright © 2011-2022 走看看