单个参数: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.xml文档实例的更多相关文章

  1. JavaScript 解析读取XML文档 实例代码(转)

    JavaScript解析读取XML文件,主要就是加载并解析XML文件,然后就可以测试解析的XML文件的内容,打印输出来. 在线演示:http://demo.jb51.net/js/2012/readx ...

  2. Java高级特性 第13节 解析XML文档(1) - DOM和XPath技术

    一.使用DOM解析XML文档 DOM的全称是Document Object Model,也即文档对象模型.在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树 ...

  3. Java解析XML文档(简单实例)——dom解析xml

      一.前言 用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object ...

  4. Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Oracle 远程访问配置   服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...

  5. 【.net 深呼吸】使用二进制格式来压缩XML文档

    在相当多的情况下,咱们写入XML文件默认是使用文本格式来写入的,如果XML内容是通过网络传输,或者希望节省空间,特别是对于XML文档较大的情况,是得考虑尽可能地压缩XML文件的大小. XmlDicti ...

  6. 【Win10 应用开发】自适应Toast通知的XML文档结构

    老规矩,在开始之前老周先讲个故事. 话说公元2015年7月20日,VS 2015发布.于是,肯定有人会问老周了,C#6有啥新特性,我学不来啊.学不来的话你应该检讨.老周比较保守地计算一下,学会C# 6 ...

  7. 网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档,视频项目

    小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心: ...

  8. Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构

    分享两篇Win 10应用开发的XML文档结构:Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构. Win 10 开发中Adapt ...

  9. C#XmlHelper操作Xml文档的帮助类

    using System.Xml; using System.Data; namespace DotNet.Utilities { /// <summary> /// Xml的操作公共类 ...

随机推荐

  1. ibatis 中 $与#的区别

    ibatis 中 $与#的区别 使用#: select * from table where id = #id# 如果字段为整型:#id#表示成id select * from table where ...

  2. Prepare for Mac App Store Submission--为提交到Mac 应用商店做准备

    返回 Mac App Store Prepare for Mac App Store Submission 提交到Mac 应用商店之前的准备 Most of your time is spent on ...

  3. (4)ASP.NET Core 中间件

    1.前言 整个HTTP Request请求跟HTTP Response返回结果之间的处理流程是一个请求管道(request pipeline).而中间件(middleware)则是一种装配到请求管道以 ...

  4. hdoj3665【简单DFS】

    题意: 略. 思路: n就10而已,没有环,搜一下就好了.. #include <bits/stdc++.h> using namespace std; typedef long long ...

  5. 2016 Multi-University Training Contest 1 GCD【RMQ+二分】

    因为那时候没怎么补所以就分到了未搞分组里!!!然后因为标题如此之屌吧= =点击量很高,然后写的是无思路,23333,估计看题人真的是觉得博主就是个撒缺.废话不多说了,补题... update////2 ...

  6. POJ2488【DFS】

    阿西吧,搞清楚谁是行,谁是列啊!!! #include <stdio.h> #include <string.h> #include <math.h> #inclu ...

  7. springcloud(一) 服务拆分

    一般我们的项目如果需要从单应用服务升级到微服务,必须要将原来的服务做拆分,我这边的拆分也是基于将之前spb-demo的springboot单应用做拆分,拆分出三个应用,spb-brian-query- ...

  8. 黑客攻防技术宝典web实战篇:攻击验证机制习题

    猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 在测试一个使用joe和pass证书登录的Web应用程序的过程中,在登录阶段,在拦截代理服务 ...

  9. (七)SpringBoot使用PageHelper分页插件

    二:添加PageHelper依赖 <dependency> <groupId>com.github.pagehelper</groupId> <artifac ...

  10. Swift @objcMembers

    使用@objcMembers关键字,将类中的所有方法暴露给Objc (效果等同于为所有方法加上@objc). 示例代码: @objcMembers class MyController: UIView ...