单个参数: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"/>

myBatis参数处理 myBatis佟刚课程笔记的更多相关文章

  1. MyBatis框架 课程笔记

    MyBatis框架 课程笔记   第1章 MyBatis简介 1.1 MyBatis历史 1)MyBatis是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Softw ...

  2. MyBatis参数绑定规则及原理分析

    MyBatis参数的传递有几种不同的方法,本文通过测试用例出发,对其中的方式进行总结和说明,并对其部分源码进行分析. 一.测试用例(环境参考之前博客SSM接口编程一文 http://www.cnblo ...

  3. Spring学习笔记 1. 尚硅谷_佟刚_Spring_HelloWorld

    1,准备工作 (1)安装spring插件 搜索https://spring.io/tools/sts/all就可以下载最新的版本 下载之后不用解压,使用Eclipse进行安装.在菜单栏最右面的Help ...

  4. springMVC 接收数组参数,mybatis 接收数组参数,mybatis批量插入/批量删除案例

    案例是给一个用户赋予多个权限,多个权限用其对应的主键 id 为参数,组成了 一个id数组,传给springMVC,然后springMVC传给mybatis,然后mybatis批量插入.其实类似的场景还 ...

  5. mybatis参数查询

    单个参数查询            在mapper.xml配置文件中配置                   <select id= "selectByNu" paramet ...

  6. mybatis 参数为list时,校验list是否为空, mybatis ${}与#{}的区别,Mybatis sql in

    1.mybatis 参数为list时,校验list是否为空 2. mybatis ${}与#{}的区别 简单来说#{} 解析的是占位符?可以防止SQL注入, 比如打印出来的语句 select * fr ...

  7. (转载)深入了解MyBatis参数

    原文地址:http://blog.csdn.net/isea533/article/details/44002219 深入了解MyBatis参数 相信很多人可能都遇到过下面这些异常: "Pa ...

  8. mybatis 参数为String,用_parameter 取值

    mybatis 参数为String,if test读取该参数代码: <select id="getMaxDepartId" parameterType="java. ...

  9. MyBatis参数为Integer型并赋值为0时判断失误的问题解决

    mybatis.xml中有if判断条件判断参数不为空时,赋值为0的Integer参数被MyBatis判断为空,因此不执行<if test="param != null and para ...

随机推荐

  1. CodeForces 1103C. Johnny Solving

    题目简述:给定简单(无自环.无重边)连通无向图$G = (V, E), 1 \leq n = |V| \leq 2.5 \times 10^5, 1 \leq m = |E| \leq 5 \time ...

  2. bzoj1485: [HNOI2009]有趣的数列(Catalan数)

    1485: [HNOI2009]有趣的数列 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2105  Solved: 1117[Submit][Stat ...

  3. JZOJ4307. 【NOIP2015模拟11.3晚】喝喝喝

    Description

  4. Hello world——程序员的第一篇代码

    Hello world 是和A+B问题并驾齐驱的一道题,也是当世的经典题之一. 题目: 输出“Hello world”    样例输入 样例输出    Hello world Hello world ...

  5. Ascall码的故事

    没事发个ascall码表,二进制值得研究呦 sub al,30h; and al,00001111b ;字符ascall转数字or al,00110000b; sub al,32; and al,11 ...

  6. Hibernate中表与表之间的关联多对多,级联保存,级联删除

    第一步:创建两个实体类:用户和角色实体类,多对多关系,并让两个实体类之间互相关联: 用户实体类: package com.yinfu.entity; import java.util.HashSet; ...

  7. the little schemer 笔记(10)

    第十章 What Is  the Value of All of This? entry条目 是由list表组成的 pair 对,pair 对的第一个list表是集合 set.另外,两个list表的长 ...

  8. Android应用的安全隐患*

    转自: http://www.cnblogs.com/chi0591/p/3864747.html Android应用的安全隐患包括三个方面: 代码安全 数据安全 组件安全 代码安全 代码安全主要是指 ...

  9. 16G 手机清理

    1.16G 手机清理 清理top 5 的应用的缓存即可 2,hw wife 连接模块 低于 app wifi 的连接模块. 在同样的电脑热点面前,hw 连补上电脑热点,apple 可以连上电脑热点. ...

  10. C#方法拓展

    作用: “扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.” 要求: 1.拓展方法必须是在一个非嵌套.非泛型的静态类中定义.2.他至少有一个参数.3. ...