天天看點

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的用法就到此為止了。

繼續閱讀