背景

考虑以下场景:

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();
}

Mybatis foreach标签含义的更多相关文章

  1. mybatis <forEach>标签的使用

    MyBatis<forEach>标签的使用 你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis.当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中,用名 ...

  2. MyBatis foreach标签遍历数组

    有时候开发中需要根据多个ID去查询,可以将ID封装为List或者数组然后使用MyBatis中的foreach标签构建in条件. 这里我将ID封装为String[]作为参数. <select id ...

  3. mybatis foreach标签

    一.批量插入数据 示例:添加订单商品表 1.模型层的相应代码 /** * 添加订单商品表 * @param ordergoods * @return */ public boolean addOrde ...

  4. MyBatis foreach标签的用法

    From<MyBatis从入门到精通> 一.foreach实现in集合 1.映射文件中添加的代码: <!-- 4.4 foreach用法 SQL语句有时会使用IN关键字,例如id i ...

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

    情景:查询数据库中文章的相关文章   文章为一个表 字段tags为相关文章字符串中间用','逗号进行啦分割 查询完一个文章后可以把tags字段构造为一个List<String> 然后利用这 ...

  6. Mybatis批量insert 返回主键值和foreach标签详解

    Mybatis批量insert 返回主键 Mybatis从3.3.1版本开始,支持批量插入后返回主键ID.首先对于支持自增主键的数据库使用useGenerateKeys和keyProperty,对于不 ...

  7. mybatis <where>、<set>、<trim>、<sql>、<foreach>标签的使用

    转:http://www.cnblogs.com/lixiujie/p/5766669.html <resultMap>标签的使用:这个类似于hibernte用于映射我们创建的vo对象与数 ...

  8. MyBatis的Mapper文件的foreach标签详解

    MyBatis的Mapper文件的foreach标签用来迭代用户传递过来的Lise或者Array,让后根据迭代来拼凑或者批量处理数据.如:使用foreach来拼接in子语句. 在学习MyBatis M ...

  9. mybatis的foreach标签

    今天写sql发现了一点问题,乱弄了好久算是搞定了.关于mybatis的批量插入使用foreach插入形式为: insert into role_privilege( role_id, privileg ...

随机推荐

  1. 恢复oracle数据从delete

    今天维护系统的时候没仔细看,误删了50行数据,然后想起来以前学过delete语句删除的数据是可以回复的,但是那个时候比较慌乱,也没有心情仔细看,反而是想到了一个歪招解决了问题,我有个良好的嗜好就是经常 ...

  2. c# 反射小Demo

    今天看了一下C#的反射,之前一直感觉反射是一种很高大上的东东,现在才发现不过是纸老虎而以. 所谓的反射就是,只是知道一个它是一个对象不知道其中有什么字段方法属性等,而反射就是用来获取一个未知对象的字段 ...

  3. 《JavaScript 高级程序设计》读书笔记二 使用JavaScript

    一   <script>元素 a.四个属性: async:立即异步加载外部脚本: defer:延迟到文档完全被解析再加载外部脚本: src:外部脚本路径: type:脚本语言的内容类型: ...

  4. java继承多态和抽象类接口

    一.继承 通过扩展一个已有的类,并继承该类的属性和行为,来创建一个新的类.已有的称为父类,新的类称为子类(父类派生子类,子类继承父类).(1)继承的优点:    ①代码的可重用性:    ②父类的属性 ...

  5. electron-builder 由于网络原因无法下载问题解决

    electron-builder 由于网络原因无法下载问题解决 在package.json的build中添加electron的镜像 "electronDownload": { &q ...

  6. Python学习笔记【第十一篇】:Python面向对象高级

    isinstance(obj,cls)和issubclass(sub,super) class Person(object): def __init__(self, name, age, sex, n ...

  7. 把ajax包装成promise的形式(3)

    概述 为了体验promise的原理,我打算自己把ajax包装成promise的形式.主要希望实现下列功能: // 1.使用success和error进行链式调用,并且可以在后面加上无限个 promis ...

  8. 使用git clone命令克隆github项目到本地时出错,提示没有权限的解决方法

    最近使用 git clone 命令在Github上克隆自己项目到本地时出错:提示没有权限,确认仓库是否存在,如下图红色框所示 问题:用过 git 的小伙伴都知道克隆项目的命令是—— git clone ...

  9. 二、activiti工作流-创建25张表

    首先我们在eclipse上创建一个maven项目 然后在resources下面创建一个file,并命名问activiti.cfg.xml activiti.cfg.xml的配置内容如下 <?xm ...

  10. 使用线程统计信息(Thread Statistics)

    可在session log中使用线程统计信息来判断source,target或组的性能瓶颈 默认情况下,Integration Service在运行session时,使用一个reader thread ...