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 ...
随机推荐
- 任务13:在Core Mvc中使用Options
13 新建Controllers文件夹,在里面添加HomeController控制器 新建Views文件夹,再新建Home文件夹.再新建Index.cshtml的视图页面 注释上节课的代码,否则我们的 ...
- 斯坦福CS231n—深度学习与计算机视觉----学习笔记 课时2
课时2 计算机视觉历史回顾与介绍中 1966年是计算机视觉的诞生年. 视觉处理流程的第一步,是对简单的形状结构处理,边缘排列. 边缘决定了结构. David Marr写了一本非常有影响力的书,视觉是分 ...
- Codeforces702C【二分】
题意: 给你几个城市,蜂窝塔量: 给出城市和塔的坐标可以重叠,非递减的方式给出: 输出最小的r,以至于所有的城市能被覆盖到: 思路: 目的就是要使每个城市覆盖到,那我对每个城市找离最近塔的距离,然后在 ...
- poj1159 【LCS】
思路: 滚动数组; 贴一发挫code- #include <iostream> #include <cstdio> #include <string.h> #inc ...
- hdoj1160【DP】
现在还很弱,贴一个我bin的结题报告日后写到一定会了加油 说说感觉,读题不读好,然后读完想不出,知道是dp不好好想,先排序一列,再求另一列,dp[ i ]代表长度,那么需要输出整个序列需要路径和一个标 ...
- Django学习:url路由系统
一.MTV模型 1.Django的MTV分别代表: Model(模型):和数据库相关的,负责业务对象与数据库的对象(ORM) Template(模板):放所有的html文件 模板语法:目的是将白变量( ...
- hdu 5409 CRB and Graph(边双联通分量)
题意: 给一个图一些边,保证图连通 问对于每条边,如果去除该边后使得图中一些点不连通.设这些点(u,v),要求使u尽量小,v尽量大,输出这样的(u,v).否则输出0 0. #include <b ...
- Centos 6.8安装 SVN
SVN SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统,它的设计目标就是取代CVS.互联网上很多版本控制服务已从CVS迁移到Subver ...
- AdventureWorks2012.mdf的使用
AdventureWorks2012.mdf的使用,在数据库管理器界面中,右击数据库,然后附加,然后选择好AdventureWorks2012.mdf,然后删掉log,然后确定即可.
- Python 教程资源
1.廖雪峰的官方网站 http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386 ...