myBatis.xml文档实例
单个参数: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文档实例的更多相关文章
- JavaScript 解析读取XML文档 实例代码(转)
JavaScript解析读取XML文件,主要就是加载并解析XML文件,然后就可以测试解析的XML文件的内容,打印输出来. 在线演示:http://demo.jb51.net/js/2012/readx ...
- Java高级特性 第13节 解析XML文档(1) - DOM和XPath技术
一.使用DOM解析XML文档 DOM的全称是Document Object Model,也即文档对象模型.在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树 ...
- Java解析XML文档(简单实例)——dom解析xml
一.前言 用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object ...
- 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.网络监听配置 ...
- 【.net 深呼吸】使用二进制格式来压缩XML文档
在相当多的情况下,咱们写入XML文件默认是使用文本格式来写入的,如果XML内容是通过网络传输,或者希望节省空间,特别是对于XML文档较大的情况,是得考虑尽可能地压缩XML文件的大小. XmlDicti ...
- 【Win10 应用开发】自适应Toast通知的XML文档结构
老规矩,在开始之前老周先讲个故事. 话说公元2015年7月20日,VS 2015发布.于是,肯定有人会问老周了,C#6有啥新特性,我学不来啊.学不来的话你应该检讨.老周比较保守地计算一下,学会C# 6 ...
- 网络电视精灵~分析~~~~~~简单工厂模式,继承和多态,解析XML文档,视频项目
小总结: 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心: ...
- Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构
分享两篇Win 10应用开发的XML文档结构:Win 10 开发中Adaptive磁贴模板的XML文档结构,Win10 应用开发中自适应Toast通知的XML文档结构. Win 10 开发中Adapt ...
- C#XmlHelper操作Xml文档的帮助类
using System.Xml; using System.Data; namespace DotNet.Utilities { /// <summary> /// Xml的操作公共类 ...
随机推荐
- wcf中序列化BinaryFormatter,DataContractJsonSerializer,DataContractSerializer,SoapFormatter,XmlSerializer
using System; using System.Runtime.Serialization; using System.Xml.Serialization; namespace Larryle. ...
- mfc实现对话框全屏置顶显示
一.MFC让对话框窗口始终在最前 方法一:在对话框的属性中,把SystemModal设置为True. 二.全屏显示 在CDialog7::OnInitDialog()中加入: 先取得分辨率, int ...
- 022--python 模块介绍和time模块
一.模块的含义 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代 ...
- Codeforces702C【二分】
题意: 给你几个城市,蜂窝塔量: 给出城市和塔的坐标可以重叠,非递减的方式给出: 输出最小的r,以至于所有的城市能被覆盖到: 思路: 目的就是要使每个城市覆盖到,那我对每个城市找离最近塔的距离,然后在 ...
- hdoj2859【DP基础】
/* 看题解A的. 总结:小矩阵--> 大矩阵 dp[i][j]=min(t,dp[i-1][j+1]+1); */ #include <iostream> #include < ...
- hdoj1106
果然...这种一条字符串的处理,还是不熟练,居然wa了四次--. 预处理预处理!!!!: 然后中间对条件的确定,标记的改变+预处理,不够严谨啊!!! #include<cstdio> #i ...
- Unity里的人物驱动/换装备/换武器/换衣服/卡通重定位(转)
Unity里的人物驱动/换装备/换武器/换衣服/动画重定位 刚学的过程被这个问题困扰最多. 首先,基本的,大家都知道驱动人物需要骨架.绑骨的Mesh和动画(这三个要是不知道的话就得考虑看看计算机图形学 ...
- P5167 xtq的神笔
传送门 题解 倍增也好二分也好,果然复杂度只要和\(\log\)插上关系就没我啥事了-- 首先由一个显而易见然而我完全没有发现的结论,设\(calc(l,r)\)表示区间\([l,r]\)的\(or\ ...
- PowerDesigner 16.5的下载安装破解注册(图文详解)
http://blog.csdn.net/chenchunlin526/article/details/54707757
- 【模板】c++动态数组vector
相信大家都知道$C$++里有一个流弊的$STL$模板库.. 今天我们就要谈一谈这里面的一个容器:动态数组$vector$. $vector$实际上类似于$a[]$这个东西,也就是说它重载了$[]$运算 ...