天天看点

MyBatis中foreach用法

foreach用法

SQL语句中有时会使用in关键字,如id in {1,2,3},我们可以使用${ids}方式直接获取值,但是这种方法不能防止SQL注入,想避免SQL注入的话就需要使用#{id}的方式,这时我们就可以配合使用foreach标签了。foreach可以对数组、Map或实现了Iterable接口(List、Set)的对象进行遍历。数组在处理时会转换为List对象,因此foreach遍历的对象可以分为两大类:Iterable类型和Map类型。

foreach实现in集合

foreach实现in集合或数组是最简单和最常用的一种情况。假设,我们需要根据传入的用户id集合来查询所有符合条件的用户。在接口类中写一个方法,selectByIdList(List<Long> idList)。

package Interface;

import pojo.User;

import java.util.List;

public interface UserMapper {
    //foreach实现in集合
    List<User> selectByIdList(List<Long> idList);

}
           
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="Interface.UserMapper">     
    <!--foreach实现in集合-->
    <select id="selectByIdList" resultType="pojo.User">
        select id,user_name userName,user_password userPassword,
        user_email userEmail,user_info userInfo,head_img headImg,create_time createTime
        from t_user where id in
        <foreach collection="list" open="(" close=")" separator="," item="id" index="i">
            #{id}
        </foreach>
    </select>
</mapper>
           

foreach中包含以下属性:

  • collection:必填。值为要迭代循环的属性名。这个属性值的情况很多。
  • item:变量名,值为从迭代对象中取出的每一个值。
  • index:索引的属性名,在集合数组情况下值为当前索引值,当迭代循环的对象是Map类型时,这个值即为Map的key值。
  • open:整个循环内容开头的字符串。
  • close:整个循环内容结尾的字符串。
  • separator:每次循环的分隔符。

collection属性的设置:

  • 当只有一个数组参数或集合参数

当参数类型为集合的时候,默认会转换为Map类型,并添加一个key为collection的值,如果参数类型是List集合,那么就继续添加一个key为list的值,这样当collection = list时就能得到这个集合,并对它进行循环操作。当参数类型为数组的时候,也会转换成Map类型,默认的key值为array。如selectByIdList(List<Long> idList),collection属性值就为array。

  • 当有多个参数

当有多个参数的时候,就要使用@Param注解给每个参数指定一个名字,否则在SQL中使用参数时就会不方便,因此将collection设置为@Param注解指定的名字即可。

  • 当参数是Map类型

使用Map和使用@Param注解方式类似,将collection指定为对应Map中的key即可。如果要循环所传入的Map,推荐使用@Param注解指定名字,此时可将collection设置为指定的名字,如果不想指定名字,就是用默认值_parameter。

  • 当参数是一个对象

这种情况下指定为对象的属性名即可。当使用对象内多层嵌套的对象时,使用属性.属性(集合和数组可使用下标取值)的方法指定深层的属性值。

测试方法:

@Test
    public void testSelectByIdList() {
        SqlSession sqlSession = getSqlSession();
        try {
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            List<Long> idList = new ArrayList<Long>();
            idList.add(1001L);
            idList.add(1002L);
            idList.add(1003L);
            idList.add(1004L);
            List<User> userList = userMapper.selectByIdList(idList);
            for (User user : userList) {
                System.out.println(user);
            }
        } finally {
            sqlSession.close();
        }
    }
           
MyBatis中foreach用法

foreach实现批量插入

定义一个方法:insertList()

package Interface;

import pojo.User;

import java.util.List;

public interface UserMapper {
    //foreach实现批量插入
    int insertList(List<User> userList);

}
           
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="Interface.UserMapper">     
    <!--foreach实现批量插入-->
    <insert id="insertList">
        insert into t_user(user_name,user_password,user_email,user_info,head_img,create_time)
        values
        <foreach collection="list" item="user" separator=",">
        (#{user.userName},#{user.userPassword},#{user.userEmail},#{user.userInfo},
        #{user.headImg,jdbcType=BLOB},#{user.createTime,jdbcType=TIMESTAMP})
        </foreach>
    </insert>
</mapper>
           
@Test
    public void testInsertList() {
        SqlSession sqlSession = getSqlSession();
        try {
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            List<User> userList = new ArrayList<User>();
            for(int i = 1; i <= 3; i++) {
                User user = new User();
                user.setUserName("study" + i);
                user.setUserPassword("!@#$%^");
                user.setUserEmail("[email protected]");
                user.setUserInfo("okokok");
                user.setHeadImg(new byte[]{1});
                user.setCreateTime(new Date());
                userList.add(user);
            }
            int res = userMapper.insertList(userList);
            if (res > 0) {
                System.out.println(res);
                System.out.println("插入成功!");
            }
        } finally {
            sqlSession.commit();
            sqlSession.close();
        }
    }
           
MyBatis中foreach用法
MyBatis中foreach用法

foreach实现动态update

当参数是Map,foreach标签的index属性值对应的不是索引值,而是Map中的key,利用这个key可以实现动态更新。

package Interface;

import pojo.User;

import java.util.List;
import java.util.Map;

public interface UserMapper {
    //foreach实现动态更新
    int updateByMap(Map<String,Object> map);

}
           
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="Interface.UserMapper">     
    <!--foreach实现动态更新-->
    <update id="updateByMap">
        update t_user set
        <foreach collection="_parameter" item="val" index="key" separator=",">
            ${key} = #{val}
        </foreach>
        where id = #{id}
    </update>
</mapper>
           

key作为列名,对应的值作为该列的值,通过foreach将需要更新的字段拼接在SQL语句中。

@Test
    public void testUpdateByMap() {
        SqlSession sqlSession = getSqlSession();
        try {
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            Map<String,Object> map = new HashMap<String, Object>();
            //查询条件,也是更新条件,必须保证值存在
            map.put("id",1007L);
            //要更新的其他字段
            map.put("user_password","testst");
            map.put("user_email","[email protected]");
            int res = userMapper.updateByMap(map);
            if(res > 0) {
                System.out.println(res);
                System.out.println("更新成功!");
            }
        } finally {
            sqlSession.commit();
            sqlSession.close();
        }
    }
           
MyBatis中foreach用法
MyBatis中foreach用法

至此,foreach的用法就到此为止了。

继续阅读