1.foreach
foreach用在mapper文件中可以在SQL语句中进行迭代一个集合。
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名,
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,一般为"(",常用在 in(),values()中,与close属性一起使用
separator表示在每次进行迭代之间以什么符号作为分隔符,一般为","
close表示以什么结束,一般为")"
collection属性是在使用foreach的时候最关键的也是最容易出错的,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,如果接口文件中没有指定@Param参数 ,主要有一下3种情况:
1.当传入要迭代的集合为List时,collection属性写作list.
<select id="findUserListByIdList" parameterType="java.util.ArrayList" resultType="User">
select * from user user
<where>
user.ID in
<foreach item="user" index="index" collection="list" open="(" close=")"
separator=","> #{user} </foreach>
</where>
</select>
2.当传入的集合为数组时,collection属性写作array:
<select id="findUserListByIdList" parameterType="java.util.HashList" resultType="User">
select * from user user
<where>
user.ID in
<foreach item="user" index="index" collection="array" open="(" close=")"
separator=","> #{user} </foreach>
</where>
</select>
3.当传入集合为map时,collection属性为map中对应要迭代的集合的key,如
①当map中有一个key为idList的集合时,collection写作"idList"
<select id="exists" parameterType="java.util.HashMap" resultType="java.lang.Integer">
SELECT COUNT(*) FROM USER user
<where>
<if test="idList !=null ">
user.ID in (
<foreach item="user" index="index" collection="idList"
separator=","> #{user} </foreach>
)
</if>
</where>
</select>
②当要遍历当前map时,由于map没有默认的别名,需要在接口文件中标注@Param参数,指定map的名字
public interface XXXDao {
public void saveXXX(@Param("params")Map<String, String> params);
}
xml文件中:通过params.keys获取键的集合,param.value获取值集合
<insert id="XXX" parameterType="java.util.Map">
INSERT INTO table
<foreach collection="params.keys" item="key" open="(" separator="," close=")">
获取值:#{param[key]}
键:#{key}
</foreach>
VALUES
<foreach collection="param.value" item="val" open="(" separator="," close=")">
值:#{val}
</foreach>
</insert>
也可以通过params.entrySet()获取集合
<insert id="XXX" parameterType="java.util.Map">
INSERT INTO table(a, b)
VALUES
<foreach collection="params.entrySet()" open="
(" separator="," close=")" index="key" item="val">
#{key}, #{val}
</foreach>
</insert>
4.当传入类型为对象类型,若对象中有list或array时,foreach中的collection必须是具体list或array在BEAN中的变量名。
<select id="findUserListByDTO" parameterType="UserDTO" resultType="java.lang.Integer">
SELECT COUNT(*) FROM USER user
<where>
<if test="idList !=null ">
user.ID in (
<foreach item="guard" index="index" collection="idList"
separator=","> #{guard} </foreach>
)
</if>
</where>
</select>
结论:
foreach遍历的对象,作为入参时,List对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。也就是传入的集合(list,array,map)的名字,这个名字可以在foreach里面随便引用)
当然在作为入参时可以使用@Param("params")来设置键,设置keyName后,list,array将会失效。建议设置@Param属性来指定keyName.