Mybatis 示例之 foreach (下)

 

 

 

 

 

这节讲的是foreach中map的用法。

 

 

 

map和List,array相比,map是用K,V存储的,在foreach中,使用map时,index属性值为map中的Key的值。

 

 

 

因为map中的Key不同于list,array中的索引,所以会有更丰富的用法。

 

 

 

第一个简单例子:

 

 
  1. <insert id="ins_string_string">  
  2.         insert into string_string (key, value) values  
  3.         <foreach item="item" index="key" collection="map"  
  4.             open="" separator="," close="">(#{key}, #{item})</foreach>  
  5.     </insert>  


可以看到这个例子相当简单,表中需要两个值,正好和K,V对应,因而map中的一个K,V就对应一条数据,如果map中有多个K,V,就会保存多个结果。

如果map中有两对K,V,那么执行SQL如下:

 

 
  1. DEBUG [main] - ==>  Preparing: insert into string_string (key, value) values (?, ?) , (?, ?)   
  2. DEBUG [main] - ==> Parameters: key 1(String), value 1(String), key 2(String), value 2(String)  
  3. DEBUG [main] - <==    Updates: 2  


大部分数据库是支持values()()这种形式的插入语句,可以插入多条。

 

 

下面再看一个select的例子:

 

 
  1. <select id="sel_key_cols" resultType="int">  
  2.         select count(*) from key_cols where  
  3.         <foreach item="item" index="key" collection="map"  
  4.             open="" separator="AND" close="">${key} = #{item}</foreach>  
  5.     </select>  


可以看到这里用key=value来作为查询条件,对于动态的查询,这种处理方式可以借鉴。一定要注意到$和#的区别,$的参数直接输出,#的参数会被替换为?,然后传入参数值执行。

 

 

上述SQL执行日志如下:

 

 
  1. DEBUG [main] - ==>  Preparing: select count(*) from key_cols where col_a = ? AND col_b = ?   
  2. DEBUG [main] - ==> Parameters: 22(Integer), 222(Integer)  
  3. DEBUG [main] - <==      Total: 1  

 

最后,如果不考虑元素的顺序和map中Key,map和list,array可以拥有一样的效果,都是存储了多个值,然后循环读取出来。

 

 

 

 
 
### MyBatis 中使用 `foreach` 标签以 Map 作为参数的示例MyBatis 的 SQL 映射文件中,可以利用 `<foreach>` 标签来处理集合类型的参数。当需要传递一个复杂的结构(如 `Map` 或其他容器对象)时,可以通过定义合适的键值对实现动态查询功能。 以下是基于用户需求的一个具体示例: #### XML 配置示例 假设我们需要根据一组角色 ID 查询对应的用户信息,并允许额外条件过滤(例如用户名模糊匹配)。SQL 映射配置如下所示: ```xml <select id="getUserByRolesAndName" resultMap="userRoleResultMap" parameterType="java.util.Map"> SELECT tuser.ID AS user_id, tuser.NAME AS user_name, trole.ID AS role_id, trole.TEXT AS role_text FROM tuser JOIN tuser_trole ON tuser.ID = tuser_trole.USER_ID JOIN trole ON tuser_trole.ROLE_ID = trole.ID WHERE 1=1 <!-- 判断是否有名字参数 --> <if test="name != null and name != ''"> AND tuser.NAME LIKE CONCAT('%', #{name}, '%') </if> <!-- 处理角色ID列 --> <if test="roles != null and roles.size > 0"> AND trole.ID IN <foreach collection="roles" item="roleId" open="(" separator="," close=")"> #{roleId} </foreach> </if> </select> ``` #### 关于代码解释 - **`parameterType="java.util.Map"`**: 明该方法接收的是一个 `Map` 类型的参数[^4]。 - **`<if>` 条件判断**: 动态拼接 SQL 字符串,仅在满足特定条件下才加入对应字段[^4]。 - **`<foreach>` 循环标签**: - 属性说明: - `collection`: 指定要迭代的集合名称,在这里是 `Map` 中的 key 值 `"roles"`。 - `item`: 迭代变量名,每次循环取出当前项并赋为此变量名。 - `open`, `close`: 定义整个达式的起始和结束符号[^3]。 - `separator`: 各元素之间的分隔符。 #### 调用方式 在 Java 方法中调用此接口时,传入一个包含必要数据的 `HashMap` 即可完成操作。例如: ```java import java.util.HashMap; import java.util.List; public List<UserWithRoles> getUserByRolesAndName(List<Integer> roleIds, String userName) { HashMap<String, Object> params = new HashMap<>(); params.put("roles", roleIds); // 设置角色ID列 if (userName != null && !"".equals(userName.trim())) { // 如果存在姓名,则设置 params.put("name", userName); } return sqlSession.selectList("namespace.getUserByRolesAndName", params); } ``` --- ### 注意事项 1. 当前设计支持灵活扩展更多筛选条件,只需按照相同逻辑增加新的 `<if>` 和绑定参数即可[^4]。 2. 若输入的角色 ID 数组为空或者未提供任何有效值,则不会触发 `IN (...)` 子句。 3. 使用 `CONCAT()` 函数构建模糊匹配字符串是为了兼容 MySQL 数据库语法;对于其他数据库可能需调整相应写法。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值