欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Mybatis foreach标签含义

程序员文章站 2023-10-17 10:17:35
背景 考虑以下场景: InfoTable(信息表): | Name | Gender | Age | Score | | | | | | | 张三 | 男 | 21 | 90 | | 李四 | 女 | 20 | 87 | | 王五 | 男 | 22 | 92 | | 赵六 | 女 | 19 | 94 ......

背景

考虑以下场景:

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,实际上如果你在传入参数的时候,在里面也是会把它封装成一个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中属性的含义 之 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();
}