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"/>

































  • 相关阅读:
    Vue 单向数据流&双向数据绑定原理
    Arguments对象
    类数组对象(array-like objects)
    ...theArgs剩余参数
    vue 深度选择器/deep/报错(标红)
    修改mandMobile下拉菜单样式
    PC端input maxlength 失效问题
    el-input 正则限制输入为非负整数
    Mac鼠标左右键都是右键
    Vue双向数据绑定简易实现
  • 原文地址:https://www.cnblogs.com/zjulanjian/p/9194911.html
Copyright © 2011-2022 走看看