Mybatis foreach标签含义

背景

考虑以下场景:

InfoTable(信息表):

Name

Gender

Age

Score

张三

21

90

李四

20

87

王五

22

92

赵六

19

94

孙七

23

88

周八

20

91

StatusTable(状态表,指是否有在考试之前复习):

Name

hasReview

张三

李四

王五

赵六

孙七

周八

现在,我想知道所有复习过的学生的成绩,可以利用mysql中的子查询来实现:

SELECT Score 
FROM InfoTable 
WHERE Name in (SELECT Name 
               FROM StatusTable 
               WHERE hasReview = '是');

这种方式非常方便,我们只要把查询条件写出来,剩下的操作都由mysql来处理。而在实际场景中,为了减少底层耦合,我们一般不通过mysql中的子查询方式联表查询,而是先执行子查询得到结果集,再以结果集作为条件执行外层查询。通常情况下,子查询和外层查询由上层的不同服务执行,这样就在一定程度上达到了底层数据库解耦的目的。注意这种实现方式将mysql内部的一部分复杂操作抛给了我们。这时,Mybatis中的foreach标签就有了用武之地。

Mybatis 中foreach标签的用法

还以刚才的例子来说,先执行子查询

SELECT Name FROM StatusTable WHERE hasReview = '是'

再执行外层查询,就是

SELECT Score 
FROM InfoTable 
WHERE Name in ('张三' , '王五', '赵六', '周八');

也就是一个批量查询操作,将其抽象一下(假设有三个条件):

SELECT * 
FROM <tableName> 
WHERE <ColumnName> IN (<case1>,<case2>,<case3>)

实际情况中,case可能远不止3个,这时可以在XXXMapper.xml文件中利用Mybatis中的foreach编写sql语句:

SELECT * 
FROM <tableName> 
WHERE <ColumnName> IN 
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
    #{item}
</foreach>

就可以实现相同的效果了。

那么问题来了,foreach标签中各种参数是什么含义呢?

  • collection
    1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
  • index 集合迭代位置
  • item 集合中的每一个元素别名
  • open 开始符号,例如这里的(,就对应于IN (<case1>,<case2>,<case3>)中IN后面的第一个(
  • separator 分隔符,例如这里的,,就对应于IN (<case1>,<case2>,<case3>)中的,
  • close 结束符号,例如这里的),就对应于IN (<case1>,<case2>,<case3>)<case3>后面的)

参考

mybatis foreach标签的解释 与常用之处

Mybatis中属性的含义 之 collection 1.eg: <select id="getEmpsInNames" resultType="emp"> select * from emp where ename in <foreach collection="list" index="index" item="name" open="(" separator="," close=")"> #{name} </foreach> </select> 对应的测试代码: @Test public void dynamicForeachTest() { SqlSession session = Util.getSqlSessionFactory().openSession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); List<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(3); ids.add(6); List<Blog> blogs = blogMapper.dynamicForeachTest(ids); for (Blog blog : blogs) System.out.println(blog); session.close(); } 2.eg: <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<Blog> blogs = blogMapper.dynamicForeach2Test(ids); for (Blog blog : blogs) System.out.println(blog); session.close(); } 3.eg: ​ 自己把参数封装成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<String, Object> params); 对应测试代码: @Test public void dynamicForeach3Test() { SqlSession session = Util.getSqlSessionFactory().openSession(); BlogMapper blogMapper = session.getMapper(BlogMapper.class); final List<Integer> ids = new ArrayList<Integer>(); ids.add(1); ids.add(2); ids.add(3); ids.add(6); ids.add(7); ids.add(9); Map<String, Object> params = new HashMap<String, Object>(); params.put("ids", ids); params.put("title", "中国"); List<Blog> blogs = blogMapper.dynamicForeach3Test(params); for (Blog blog : blogs) System.out.println(blog); session.close(); }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏黑白安全

Mysql索引类型Btree和Hash的区别以及使用场景

遇到单表数据量大的时候很多开发者都会想到给相对的字段建立索引来提高性能(mysql索引的使用),但很少会去关注索引的类型该如何选择,在mysql中支持有两种类型...

26330
来自专栏杨建荣的学习笔记

MySQL数据类型(r3笔记第87天)

今天在本地装了一个MySQL的学习环境,简单的熟悉了一下。准备开始好好学习MySQL了。 学习编程语言我都是从数据类型入手。每种编程语言的数据类型都有自己的特点...

300100
来自专栏技术碎碎念

sql server 使用函数辅助查询

函数是所有语言系统下都具备的内部数据处理过程,SQL SERVER也同样内置了许多函数。在SQL SERVER中,函数是由一个或多个T-SQL语句组成的子程序。...

35140
来自专栏JetpropelledSnake

Django学习笔记之Models与ORM操作

12160
来自专栏芋道源码1024

数据库中间件 Sharding-JDBC 源码分析 —— SQL 解析(一)之语法解析

1. 概述 2. Lexer 词法解析器 3. Token 词法标记 3.2.1 Literals.IDENTIFIER 词法关键词 3.2.2 Litera...

45980
来自专栏iOS 开发杂谈

浅谈 Objective-C Associated Objects

Associated Objects 是 Objective-C 2.0 中 Runtime 的特性之一。 在 <objc/runtime.h> 中定义的三个...

12030
来自专栏醉生梦死

MySQL常用函数 原

SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(NOW()));

12820
来自专栏逸鹏说道

C# 温故而知新:Stream篇(二)

TextReader 和StreamReader 目录: 为什么要介绍 TextReader? TextReader的常用属性和方法 TextReader 示例...

34950
来自专栏JavaEE

mybatis笔记整理mybatis的基本用法及配置:

401110
来自专栏Java呓语

第9章、语言结构

字符串是包含在单引号(')或双引号(")字符中的字节或字符序列。 以下几行例子是等同的:

9430

扫码关注云+社区

领取腾讯云代金券