MyBatis教程大全


 MyBatis SQL 映射

     MyBatis select 标签

     MyBatis 多数据库支持

     MyBatis selectKey 标签作用

     MyBatis @SelectKey注解用法介绍

     MyBatis @SelectKey注解用法详细介绍

     MyBatis keyProperty 属性介绍

     MyBatis insert、update 和 delete 元素

     MyBatis sql 元素

 MyBatis SQL 参数映射

     MyBatis SQL 参数映射

 MyBatis 动态SQL

     MyBatis 动态SQL与数据准备

     MyBatis if 标签

     MyBatis if else 用法

     MyBatis choose、when、otherwise 标签

     MyBatis where 标签

     MyBatis set 标签

     MyBatis foreach 标签

     MyBatis bind 标签

     MyBatis trim 标签

 MyBatis SQL 结果映射

 MyBatis SQL 结果之关系映射

 MyBatis 使用介绍

     MyBatis typeAliases 类型别名

     MyBatis typeHandlers 类型处理器

     MyBatis Transaction 事务接口

     MyBatis transactionManager 事务管理

     SqlSessionFactory 介绍

     MyBatis 核心对象 SqlSession

     MyBatis 初始化 创建 Session 实例

     MyBatis ObjectFactory 对象工厂

     MyBatis缓存机制:一级缓存和二级缓存

     MyBatis 常用注解

 MyBatis 配置文件

     MyBatis 配置文件

 MyBatis 映射

     MyBatis 映射简介

     MyBatis ResultMap 映射

     MyBatis 自动映射

     MyBatis 高级映射

     MyBatis 集合映射

     MyBatis 关联映射

     MyBatis 一对一关联映射

     MyBatis 一对多关联映射

     MyBatis 多对多关联映射

     MyBatis 一对一(注解形式)

     MyBatis 一对多(注解形式)

     MyBatis 多对多(注解形式)

     MyBatis resultMap 元素

 MyBatis 面试题库

     #{}和${}的区别是什么?

     数据库链接中断如何处理?

     数据库插入重复如何处理?

     事务执行过程中宕机的应对处理方式

     Java客户端中的一个Connection问题

MyBatis foreach 标签

备注:本文修改于2022年6月28日。

1、MyBatis foreach 标签介绍

foreach 标签主要用在构建 in 条件中,它可以在 SQL 语句中遍历一个集合。

2、MyBatis foreach 标签属性

foreach 标签的属性主要有 collection,item,index,open,separator,close。其含义如下所示:

  • collection:遍历的对象。当遍历对象是List、Array对象时,collection属性值分别默认用"list"、"array"代替,而Map对象没有默认的属性值。

注意:可以使用 @Param(“keyName”) 注解来自定义collection属性值,设置keyName后,list、array会失效。

  • item:集合元素遍历时的别名称。该参数为必选项。
  • index:在list、array中,index为元素的序号索引,但是在Map中,index为遍历元素的key值。该参数为可选项。
  • open:遍历集合时的开始符号,通常与 close=")" 搭配使用。使用场景为 IN()values()时。该参数为可选项。
  • separator:元素之间的分隔符,类比在 IN() 的时候,separator=",",最终所有遍历的元素将会以设定的逗号符号隔开。该参数为可选项。
  • close:遍历集合时的结束符号,通常与 open="(" 搭配使用。该参数为可选项。

3、collection 属性值的三种情况

如果参数类型为List时,collection的默认属性值为list,同样可以使用@Param注解自定义;

如果参数类型为Array时,collection的默认属性值为array,同样可以使用@Param注解自定义;

如果传入的参数类型为Map时,collection的属性值可为下面三种情况:

  • 遍历 map.keys
  • 遍历 map.values
  • 遍历 map.entrySet()

3.1 参数类型为 List,collection 属性值为 list

Mapper文件:

public List<User> selectByIds(List<Integer> userIds);

SQL片段:

<select id="selectByIds" resultType="cn.mybatis.domain.User">
    select * from t_users where id in
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

3.2 参数类型为 List,使用 @Param 注解自定义 collection 属性值

Mapper文件:

List<UserList> getUserInfo(@Param("userName") List<String> userName);

SQL片段:

<select id="getUserInfo" resultType="cn.mybatis.domain.User">
    SELECT * FROM t_users where
        <if test="userName!= null and userName.size() >0">
        USERNAME IN
            <foreach collection="userName" item="value" separator="," open="(" close=")">
                #{value}
            </foreach>
    </if>
</select>

3.3 参数类型为 Array,collection 属性值为 array

Mapper文件:

public List<User> selectByIds(int[] userIds);

SQL片段:

<select id="selectByIds" resultType="cn.mybatis.domain.User">
    select * from t_user where id in
    <foreach collection="array" index="index" item="item" open="(" separator="," close=")">
        #{item}
    </foreach>
</select>

3.3 参数类型为 Array,使用 @Param 注解自定义 collection 属性值

Mapper文件:

List<UserList> getUserInfo(@Param("userName") String[] userName);

SQL片段:

<select id="getUserInfo" resultType="cn.mybatis.domain.User">
    SELECT * FROM t_users where
    <if test="userName!= null and userName.length() >0">
        USERNAME IN
            <foreach collection="userName" item="value" separator="," open="(" close=")">
            #{value}
        </foreach>
    </if>
</select>

3.3 参数类型为 Map,collection 属性值分为三种情况

Mapper文件:

List<UserList> getUserInfo(@Param("user") Map<String,String> user);

第一种情况:获取Map的键值对

多字段组合条件情况下,一定要注意书写格式:括号()

<select id="getUserInfo" resultType="cn.mybatis.domain.User">
    SELECT * FROM t_users where
    <if test="user!= null and user.size() >0">
        (USERNAME,AGE) IN
        <foreach collection="user.entrySet()" item="value" index="key" separator="," open="(" close=")">
            (#{key},#{value})
        </foreach>
    </if>
</select>

第二种:参数Map类型,只需要获取key值或者value值

<select id="getUserInfo" resultType="cn.mybatis.domain.User">
    SELECT * FROM t_users where
    <if test="user!= null and user.size() >0">
    (USERNAME) IN
        <foreach collection="user.keys" item="key"  separator="," open="(" close=")">
            #{key}
        </foreach>
    </if>
</select>

第三种:参数Map类型,只需要获取value值

<select id="getUserInfo" resultType="cn.mybatis.domain.User">
    SELECT * FROM t_users where
    <if test="user!= null and user.size() >0">
        (USERNAME) IN
        <foreach collection="user.values" item="value"  separator="," open="(" close=")">
            #{key}
        </foreach>
    </if>
</select>

4、补充介绍

关于动态SQL另外一个常用的操作就是需要对一个集合进行遍历,通常发生在构建IN条件语句时。

<select id="selectEmployeeIn" resultType="cn.mybatis.domain.Employee">
    SELECT * FROM tb_employee WHERE ID in
    <foreach item="item" index="index" collection="list" open="(" separator="," close=") ">
      #{item}
    </foreach>
</select>

foreach元素的功能非常强大,它允许指定一个集合,声明可以用在元素体内的集合项和索引变量。它也允许指定开闭匹配的字符串以及在迭代中间放置分隔符。这个元素是很智能的,因此它不会随机地附加多余的分隔符。

// 根据传入的id集合查询员工
List<Employee> selectEmployeeIn(List<Integer> ids);

selectEmployeeIn方法传入的参数是一个List集合,该集合中的每一个Integer元素表示需要查询的员工的id。

public void testSelectEmployeeIn(SqlSession session)
{
    EmployeeMapper em = session.getMapper(EmployeeMapper.class);
    // 创建List集合
    List<Integer> ids = new Arraylist<Integer>();
    // 往List集合中添加两个测试数据
    ids.add(1);
    ids.add(2);
    List<Employee> list = em.selectEmployeeIn(ids);
    list.forEach(employee -> System.out.println(employee));
}

测试selectEmployeeln方法,控制台显示如下:

DEBUG [main]==> Preparing: SELECT * FROM tb employee WHERE ID in( ? , ? )
DEBUG [main]==> Parameters: 1(Integer) , 2 (Integer)
DEBUG [main]<== Total: 2
Employee [id=1,loginname=jack,password=123456,name=杰克,sex=男,age=26,phone=13902019999,sal=9800.0,state=ACTIVE]
Employee [id=2,loginname=rose,password=123456,namem露丝,sex=女,age=21,phone=13902018888,sal=6800.0,state=ACTIVE]

可以看到,执行的sql语句是一个in条件语句,返回的是List集合中的id的员工数据。