MyBatis中foreach循环的用法

一、在了解foreach之前,先了解一下mybatis传入参数及parameterType

1、我们在Dao层向对应的mapper.xml文件传递参数时,可以传递的参数有:

①、基本数据类型(如int/Integer、long/Long、float等)

②、简单引用数据类型(如String、User实体类对象等)

③、集合数据类型(如List、Map等)

我们在parameterType属性获取参数类型时,只需要与传入的参数类型相同即可,如:

①基本数据类型:Java代码:

1 User findById(Integer id);

①基本数据类型:mapper.xml代码:

1 <select id="findById" parameterType="int" resultType="com.demo.entity.User">
2         SELECT * FROM `user` where id=#{id};
3 </select>

②简单引用类型:Java代码:

1 void addUser(User user);

②简单引用类型:mapper.xml代码:

1 <insert id="addUser" parameterType="com.demo.entity.User">
2         insert into `user` values (null,#{userName},#{userAge})
3 </insert>

③集合数据类型(List):Java代码:

1 List<User> findUserListByIdList(List<Integer> idList);

③集合数据类型(List):mapper.xml代码:

<select id="findUserListByIdList" parameterType="List" resultType="User">  
    select * from `user `
    <where>  
        user.ID in   
        <foreach collection="idList" index="index" item="value" open="(" close=")" separator=","> #{value} </foreach>   
    </where>  
</select>

 二、foreach属性——collection、index、item、open、close、separator

属性描述
collection

要做foreach的对象,作为入参时,List<?>对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键
当然在作为入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
如果User有属性List ids。入参是User对象,那么这个collection = "ids"
如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = "ids.id"
上面只是举例,具体collection等于什么,就看你想对那个元素做循环。
该参数为必选。

index在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
item循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。
具体说明:在list和数组中是其中的对象,在map中是value。
该参数为必选。
openforeach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选。
closeforeach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
separator元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。

三、foreach简单使用:

(一)集合数据类型:Map<String, Object>

// 初始化一个Map数据
Map<String, Object> dataMap = new HashMap<String, Object>();
    dataMap.put("id", "0001");
    dataMap.put("name", "Tom");
    dataMap.put("age", "12");
// 将dataMap传递到Dao层
public void addUser(@Param("map") Map<String, Object> map);
// DaoMapper.xml   mapper文件
/* 这段添加语句的意思是:根据map提供的字段,向数据库user表中,添加数据(只添加指定字段的数据);注意区分mybatis中“$”与“#”的用法 */
<insert id="addUser" parameterType="Map">
    INSERT INTO `user`
    <foreach collection="map" index="key" item="value" open="("
        close=")" separator=",">
        ${key}
    </foreach>
    VALUES
    <foreach collection="map" index="key" item="value" open="("
        close=")" separator=",">
        #{value}
    </foreach>
</insert>

(二)集合数据类型:List<Map<String, Object>> (list集合中存的是map)

// 初始化一个数据
Map<String, Object> dataMap1 = new HashMap<String, Object>();
Map<String, Object> dataMap2 = new HashMap<String, Object>();
List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>();
    dataMap1.put("name", "Tom");
    dataMap1.put("age", "13");
    dataList.add(dataMap1);
    dataMap2.put("name", "Jack");
    dataMap2.put("age", "18");
    dataList.add(dataMap2);
// 将dataList传递到Dao层
public void addUser(List<Map<String, Object>> list);
// DaoMapper.xml
/* 批量向数据库中添加数据 */
<insert id="addUser" parameterType="List">
    INSERT INTO `user`(name, age) VALUES
    <foreach collection="list" index="index" item="item" separator=",">
        <foreach collection="item" index="key" item="value" open="(" close=")" separator=",">
            #{value}
        </foreach>
    </foreach>
<insert>

(三) 集合数据类型:Map<String,Object>(map集合中存的数据有:String, List(List里面存的是Map);)

// 初始化数据
// lineColumn 用来存需要添加的字段
    String lineColumn = "";
// paramsMap 用来打包整个数据,并将数据传递到Dao层
    Map<String, Object> paramsMap = new HashMap<String, Object>();
// 创建两个map,用来存对应的字段和值,一个map就是一个新用户
    Map<String, Object> dataMap1 = new HashMap<String, Object>();
    Map<String, Object> dataMap2 = new HashMap<String, Object>();
// 创建一个list,以list来存用户的map集合
    List<Map<String, Object>> linList = new ArrayList<Map<String, Object>>();
        dataMap1.put("name", "Tom");
        dataMap1.put("age", "12");
        linList.add(dataMap1);
        dataMap2.put("name", "Jack");
        dataMap2.put("age", "18");
        linList.add(dataMap2);
    for(String key : dataMap1.keySet()){
        lineColumn += key + ",";
    }
    lineColumn = lineColumn.substring(0,lineColumn.lingth() - 1);
    paramsMap.put("lineColumn", lineColumn);
    paramsMap.put("table", "user");
    paramsMap.put("lineList", lineList);
// 将paramsMap传递到Dao层
public void addUser(Map<String, Object> map);
// DaoMapper.xml; 根据map中传递的 表名, 字段名, 字段对应的数据 进行批量添加
/* 在Dao层传入的map集合做数据中,如果只需要拿map集合中某一个指定的单条数据时,在mapper.xml中可以 以 ${key} 即可拿到数据 */
<insert id="addUser" parameterType="Map">
    INSERT INTO `${table}` (${lineColumn}) VALUES
    <foreach collection="lineList" index="index" item="item" separator=",">
        <foreach collection="item" index="key" item="value" open="(" close=")" separator=",">
            #{value}
        </foreach>
    </foreach>
</insert>

(四)数据集合类型:Map(根据集合中value是否为null来选择性的向数据库添加数据)

// 初始化一个数据
Map<String, Object> dataMap = new HashMap<String, Object>();
    dataMap.put("id", "001");
    dataMap.put("name","Tom");
    dataMap.put("age", null);
// 传递到Dao层
public void addUser(@Param("map") Map<String, Object> map);
// DaoMapper.xml
/* 根据参数是否为null来选择性的向数据库添加数据 */
<insert id="addUser" parameterType="Map">
    INSERT INTO `user`
    <foreach collection="map" index="key" item="value" open="(" close=")" separator=",">
        <if test="value != null and value != ‘‘ ">
            ${key}
        </if>
    </foreach>
    VALUES
    <foreach collection="map" index="key" item="value" open="(" close=")" separator=",">
        <if test="value != null and value != ‘‘ ">
            #{value}
        </if>
    </foreach>
</insert>

*在mapper.xml中,使用"if"或者"where"标签小小的注意事项:

在使用if或者where标签时,如<if test=" id != null ">(当你传递参数是一个单类型时( user findById(Integer id); )),有可能报一个异常“There is no getter for property named ‘xxx’ in ‘class java.lang.xxx‘;

此时解决办法:

①将<if test=" id != null "> 中的“id”更改为“_parameter”;

②在接口方法中(user findById (Integer id);)添加@Param("xxx")注解,如user findById (@Param("id") Integer id)

相关推荐