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"/>
myBatis参数处理 myBatis佟刚课程笔记的更多相关文章
- MyBatis框架 课程笔记
MyBatis框架 课程笔记 第1章 MyBatis简介 1.1 MyBatis历史 1)MyBatis是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Softw ...
- MyBatis参数绑定规则及原理分析
MyBatis参数的传递有几种不同的方法,本文通过测试用例出发,对其中的方式进行总结和说明,并对其部分源码进行分析. 一.测试用例(环境参考之前博客SSM接口编程一文 http://www.cnblo ...
- Spring学习笔记 1. 尚硅谷_佟刚_Spring_HelloWorld
1,准备工作 (1)安装spring插件 搜索https://spring.io/tools/sts/all就可以下载最新的版本 下载之后不用解压,使用Eclipse进行安装.在菜单栏最右面的Help ...
- springMVC 接收数组参数,mybatis 接收数组参数,mybatis批量插入/批量删除案例
案例是给一个用户赋予多个权限,多个权限用其对应的主键 id 为参数,组成了 一个id数组,传给springMVC,然后springMVC传给mybatis,然后mybatis批量插入.其实类似的场景还 ...
- mybatis参数查询
单个参数查询 在mapper.xml配置文件中配置 <select id= "selectByNu" paramet ...
- mybatis 参数为list时,校验list是否为空, mybatis ${}与#{}的区别,Mybatis sql in
1.mybatis 参数为list时,校验list是否为空 2. mybatis ${}与#{}的区别 简单来说#{} 解析的是占位符?可以防止SQL注入, 比如打印出来的语句 select * fr ...
- (转载)深入了解MyBatis参数
原文地址:http://blog.csdn.net/isea533/article/details/44002219 深入了解MyBatis参数 相信很多人可能都遇到过下面这些异常: "Pa ...
- mybatis 参数为String,用_parameter 取值
mybatis 参数为String,if test读取该参数代码: <select id="getMaxDepartId" parameterType="java. ...
- MyBatis参数为Integer型并赋值为0时判断失误的问题解决
mybatis.xml中有if判断条件判断参数不为空时,赋值为0的Integer参数被MyBatis判断为空,因此不执行<if test="param != null and para ...
随机推荐
- STL--lower_bound()&upper_bound();
又是两个黑科技一般的存在. 首先我们来介绍一下这两个函数: ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& ...
- 时间戳 js 转换
// 获取当前时间戳(以s为单位) var timestamp = Date.parse(new Date()); timestamp = timestamp / 1000; //当前时间戳为:140 ...
- POJ 3419 Difference Is Beautiful (DP + 二分 + rmq)
题意:给n个数(n<=200000),每个数的绝对值不超过(10^6),有m个查询(m<=200000),每次查询区间[a,b]中连续的没有相同数的的最大长度. 析:由于n太大,无法暴力, ...
- 在Emacs中使用ECB(转载)
转自:http://joerong666.iteye.com/blog/1813876 By: 潘云登 Date: 2009-7-9 Email: ...
- BZOJ3834:Solar Panels (分块)
题意 询问两个区间[smin,smax],[wmin,smax]中是否存在k的倍数,使得k最大 分析 将其转化成\([\frac{smin-1}k,\frac{smax}k],[\frac{wmin- ...
- vector刘汝佳算法入门学习笔记
//*****-*-----vector***/////// 常用操作封装,a.size();可以读取大小 a.resize();可以改变大小: ...
- 鸟哥私房菜基础篇:Linux 的档案权限与目录配置习题
猫宁!!! 参考链接:http://linux.vbird.org/linux_basic/0210filepermission.php 鸟哥是为中国信息技术发展做出巨大贡献的人. 1-早期的 Uni ...
- Fiddler 学习
Little Skill Fiddler 官网: https://www.telerik.com/fiddler 来自 https://www.cnblogs.com/zhaoyanjun/p/706 ...
- 跟我一起玩Win32开发(16):ListView的多个视图
在上一个例子中,我们只用到了ListView的Report视图,也就是详细视图.本文我们再把上一篇文章中所用的例子进行一下扩展,例子源码可以到俺的资源区下载. 我们为ListView中显示的数据加上图 ...
- pika消息中间件模块
参考: http://www.rabbitmq.com/tutorials/tutorial-one-python.html http://www.rabbitmq.com/tutorials/tut ...