一 foreach元素
foreach元素的属性主要有 item,index,collection,open,separator,close。
collection属性的值有三个分别是list、array、map三种,分别对应的参数类型为:List、数组、map集合,我在上面传的参数为数组,所以值为array
item表示集合中每一个元素进行迭代时的别名,
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔 符,
close表示以什么结束。
foreach在insert的sql中, 注重点: 传入多条数据的语法
insert into t_table(id,name) values (1,"小红"),(2,"小赵"),(3,"小周")
每对括号都要求在foreach 的时候添加, 而不是最后再添加
foreach在select 和delete 的sql中, 主要是用于构建in条件
select name from t_table where id in (1,2,3,4,5)
delete from t_table where id in (1,2,3,4,5)
语法一: 参数为单个
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
语法二: 参数为多个 ,多用于插入多条数据且多参数的时候
如: 一个id 下,含有多个用户 (id - userList)
<foreach collection="list" index="index" item="item" separator="," >
(#{id}, #{item})
</foreach>
二. 如何在insert中使用foreach
t_gray_users 灰度用户表
popwindow_id
int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘弹屏id’,
user_id
varchar(100) NOT NULL DEFAULT ‘’ COMMENT ‘用户id’,
普通sql:
插入多参数-多行弹屏数据:
Insert into t_gray_users(popwindow_id,user_id) values (337,188XXXXXXXX),(337,178XXXXXXXX),(338,138XXXXXXXX)
mybatis:
插入多行弹屏数据:
<insert id="addGrayUsers" >
INSERT INTO t_gray_users
(popwindow_id, user_id)
VALUES
<foreach collection="userList" index="index" item="item" separator=",">
(#{popwindowId},#{item})
</foreach>
</insert>
错误mapper代码:
<insert id="addGrayUsers" >
INSERT INTO t_gray_users
(popwindow_id, user_id)
VALUES
<foreach collection="userList" index="index" item="item" separator="," open="(" close=")">
#{popwindowId},#{item}
</foreach>
</insert>
sql显示结果如下:
insert into t_gray_users(ipopwindow_id, user_id) values (1,"188",2,"199",3,"189")
因为该代码在插入所有数据之后,才给添加后的一大串数据添加"()",显然不符合插入多条数据的sql格式.
三. 如何在select中使用foreach
案例一: 在固定时间范围内,查询已有套餐订单的数量
mybatis:
int checkPackageOrderNum(@Param("list") List<PackageOrderDto> list, @Param("start") String start, @Param("end")String end);
mapper:
<select id="checkPackageOrderNum" resultType="java.lang.Integer">
SELECT COUNT(1) FROM t_package_order
WHERE enable = 1
<foreach collection="list" index="index" item="item">
AND ((#{item.startTime} >= #{start} AND #{item.startTime} < #{end})
OR (#{item.endTime} > #{start} AND #{item.endTime} <= #{end}))
</foreach>
</select>
注: 其实,这种写法是不必要的, 因为三个参数都是传递进来的, 可以直接写在业务逻辑里面, 不必在数据库里查询.