Mybatis foreach的用法
本文援引:https://www.cnblogs.com/fnlingnzb-learner/p/10566452.html
在做mybatis的mapper.xml文件的时候,我们时常用到这样的情况:动态生成sql语句的查询条件,这个时候我们就可以用mybatis的foreach了
foreach元素的属性主要有item,index,collection,open,separator,close。
- item:集合中元素迭代时的别名,该参数为必选。
- index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选
- open:foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选
- separator:元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
- close: foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
- collection: 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键,Map对象没有默认的键。当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List ids。入参是User对象,那么这个collection = "ids".如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"
在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
- 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list .
- 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array .
- 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key.
针对最后一条,我们来看一下官方说法:
注意 你可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。List 实例将会以“list”作为键,而数组实例的键将是“array”。
所以,不管是多参数还是单参数的list,array类型,都可以封装为map进行传递。如果传递的是一个List,则mybatis会封装为一个list为key,list值为object的map,如果是array,则封装成一个array为key,array的值为object的map,如果自己封装呢,则colloection里放的是自己封装的map里的key值。
使用方法:
1.单参数List类型
<select id="countByUserList" resultType="_int" parameterType="list">
select count(*) from users
<where>
id in
<foreach item="item" collection="list" separator="," open="(" close=")" index="">
#{item.id, jdbcType=NUMERIC}
</foreach>
</where>
</select>
测试代码:
@Test
public void shouldHandleComplexNullItem() {
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
Mapper mapper = sqlSession.getMapper(Mapper.class);
User user1 = new User();
user1.setId(2);
user1.setName("User2");
List<User> users = new ArrayList<User>();
users.add(user1);
users.add(null);
int count = mapper.countByUserList(users);
Assert.assertEquals(1, count);
} finally {
sqlSession.close();
}
}
2.单参数Array数组类型:
<select id="dynamicForeach2Test" resultType="Blog">
select * from t_blog where id in
<foreach collection="array" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
测试代码:
@Test
public void dynamicForeach2Test() {
SqlSession session = Util.getSqlSessionFactory().openSession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
int[] ids = new int[] {1,3,6,9};
List blogs = blogMapper.dynamicForeach2Test(ids);
for (Blog blog : blogs)
System.out.println(blog);
session.close();
}
3.自己把参数封账成Map类型:
<select id="dynamicForeach3Test" resultType="Blog">
select * from t_blog where title like "%"#{title}"%" and id in
<foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
上述collection的值为ids,是传入的参数Map的key,对应的Mapper代码:
public List dynamicForeach3Test(Map params);
对应测试代码:
@Test
public void dynamicForeach3Test() {
SqlSession session = Util.getSqlSessionFactory().openSession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
final List ids = new ArrayList();
ids.add(1);
ids.add(2);
ids.add(3);
ids.add(6);
ids.add(7);
ids.add(9);
Map params = new HashMap();
params.put("ids", ids);
params.put("title", "中国");
List blogs = blogMapper.dynamicForeach3Test(params);
for (Blog blog : blogs)
System.out.println(blog);
session.close();
}
4.使用foreach进行批量更新:
<update id="updateBatch" parameterType="java.util.List">
<foreach collection="list" item="feedbackReply" separator=";" index="index">
update feedback_reply
<set>
<if test="feedbackReply.replyTime!=null">
reply_time = #{feedbackReply.replyTime,jdbcType=TIMESTAMP},
</if>
<if test="feedbackReply.replyPeolpeName!=null and feedbackReply.replyPeolpeName!='' ">
reply_peolpe_name = #{feedbackReply.replyPeolpeName,jdbcType=VARCHAR},
</if>
<if test="feedbackReply.feedbackContent!=null and feedbackReply.feedbackContent!='' ">
feedback_content = #{feedbackReply.feedbackContent,jdbcType=VARCHAR},
</if>
<if test="feedbackReply.isRead!=null">
is_read = #{feedbackReply.isRead,jdbcType=INTEGER},
</if>
</set>
where id = #{feedbackReply.id,jdbcType=INTEGER}
</foreach>
</update>
其中separator属性是分号;执行的sql是这样的:
update feedback_reply set is_read = 1 where id = 1;update feedback_reply set is_read = 1 where id =2
5.使用foreach进行批量插入:
<insert id="insertBatch" parameterType="java.util.List">
insert into feedback_picture(feedback_id, picture_address)
values
<foreach collection="list" item="feedbackpicture" separator="," index="index">
(#{feedbackpicture.feedbackId,jdbcType=INTEGER},#{feedbackpicture.pictureAddress,jdbcType=VARCHAR})
</foreach>
</insert>
执行的sql是这样的:
insert into feedback_picture(feedback_id,picture_address) values(255,"agagagagagagag"),(266,"afagegarrhrljkdk")
Mybatis foreach的用法的更多相关文章
- Mybatis动态SQL——if,where,trim,choose,set.foreach的用法
知识点:主要介绍mybatis中,动态sql中的if,where,trim,set,foreach的用法 自学谷粒学院mybatis学习视频,参考mybatis官方文档 java包:log4j.jar ...
- Mybatis foreach标签含义
背景 考虑以下场景: InfoTable(信息表): Name Gender Age Score 张三 男 21 90 李四 女 20 87 王五 男 22 92 赵六 女 19 94 孙七 女 23 ...
- 解决mybatis foreach 错误: Parameter '__frch_item_0' not found
解决mybatis foreach 错误: Parameter '__frch_item_0' not found 在遍历对象的属性(是ArrayList对象)时报错: org.mybatis.spr ...
- Mybatis foreach
批量删除: <delete id= "deleteBatchByXXX" parameterType= "list"> delete from 表名 ...
- mybatis foreach批量插入数据:Oracle与MySQL区别
mybatis foreach批量插入数据:Oracle与MySQL不同点: 主要不同点在于foreach标签内separator属性的设置问题: separator设置为","分 ...
- mybatis foreach报错It was either not specified and/or could not be found for the javaType Type handler
或许是惯性思维,在mybatis使用foreach循环调用的时候,很多时候都是传一个对象,传一个List的情况很少,所以写代码有时候会不注意就用惯性思维方法做了. 今天向sql传参,传了一个List作 ...
- mybatis foreach 循环 list(map)
直接上代码: 整体需求就是: 1.分页对象里面有map map里面又有数组对象 2.分页对象里面有list list里面有map map里面有数组对象. public class Page { pri ...
- mybatis <forEach>标签的使用
MyBatis<forEach>标签的使用 你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis.当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中,用名 ...
- jstl标签forEach的用法--遍历java的集合
再讲<c:forEach>之前,现讲一下让EL表达式生效的语句 <% @ page isELIgnored="false"%>这句语句在你想让EL表达式生效 ...
随机推荐
- 云南农业职业技术学院 - 互联网技术学院 - 美和易思《MYSQL 高级查询与编程》 综合机试试卷
数据库及试题文档下载:https://download.csdn.net/download/weixin_44893902/14503097 目录 题目:电商平台 mysql 数据库系统管理 一. 语 ...
- Kafka基础教程(二):Kafka安装
因为kafka是基于Zookeeper的,而Zookeeper一般都是一个分布式的集群,尽管kafka有自带Zookeeper,但是一般不使用自带的,都是使用外部安装的,所以首先我们需要安装Zooke ...
- vsconde launch.json配置 调试本地文件
{ // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing ...
- JMeter跨线程,怎么定义全局变量,跨线程使用变量?
JMeter跨线程时,怎么定义全局变量,跨线程使用此变量? 通过函数助手,获取到设置变量的语法脚本 2.通过Bean shell Sampler取样器,定义全局变量 3.定义好全局变量,可以调用,调用 ...
- CentOS 系统 查看 cpu核数
转载自 :Centos下查看cpu核数 - 韩憨 - 博客园 (cnblogs.com) 1.概念物理CPU:实际Server中插槽上的CPU个数.物理cpu数量:可以数不重复的 physical i ...
- 初识python 之 爬虫:爬取双色球中奖号码信息
人生还是要有梦想的,毕竟还有python.比如,通过python来搞一搞彩票(双色球).注:此文仅用于python学习,结果仅作参考.用到知识点:1.爬取网页基础数据2.将数据写入excel文件3.将 ...
- java 封装 总结
1.前言 老是被问什么是java 封装...很基础的一个问题 ,其实我们一直在写的东西但不知道怎么称呼. 比如 在entity实体类 里面老用到的 getter 和 setter 方法其实就是封装的方 ...
- 【Java常用类】Math
Math 说明 java.lang.Math提供了一系列静态方法用于科学计算.其方法的参数和返回 值类型一般为double型. 方法 abs 绝对值 acos,asin,atan,cos,sin,ta ...
- 【VictoriaMetrics】vm单机版和vm-storage的查询功能的对比
1.vm-storage源码调用表 文件 行号 函数 说明 app/vmstorage/main.go 53 main 入口94行调用srv.RunVMSelect() app/vmstorage/t ...
- 学习AJAX必知必会(1)~Ajax
一.ajax(Asynchronous JavaScript And XML,即异步的 JS 和 XML) 1.通过 AJAX 可以在浏览器中向服务器发送异步请求实现无刷新获取数据. 2.优势:无刷新 ...