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();
}
}
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();
}
}
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();
}
}
至此,foreach的用法就到此為止了。