inline lan arrays tro edi rip property concat
作者:学无先后 达者为先
作者:偶尔记一下
foreach 一共有三种类型,分别为 List,[](array),Map 三种。
下面表格是我总结的各个属性的用途和注意点。
属性 | 描述 |
---|---|
item | 循环体中的具体对象。支持属性的点路径访问,如 item.age,item.info.details。 具体说明:在 list 和数组中是其中的对象,在 map 中是 value。 该参数为必选。 |
collection | 要做 foreach 的对象,作为入参时,List 对象默认用 list 代替作为键,数组对象有 array 代替作为键,Map 对象没有默认的键。 [email protected]("keyName") 来设置键,设置 keyName 后,list,array 将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子: 如果 User 有属性 List ids。入参是 User 对象,那么这个 collection = "ids" 如果 User 有属性 Ids ids; 其中 Ids 是个对象,Ids 有个属性 List id; 入参是 User 对象,那么 collection = "ids.id" 上面只是举例,具体 collection 等于什么,就看你想对那个元素做循环。 该参数为必选。 |
separator | 元素之间的分隔符,例如在 in() 的时候,separator=","会自动在元素中间用","隔开,避免手动输入逗号导致 sql 错误,如 in(1,2,) 这样。该参数可选。 |
open | foreach 代码的开始符号,一般是 (和 close=")" 合用。常用在 in(),values() 时。该参数可选。 |
close | foreach 代码的关闭符号,一般是) 和 open="("合用。常用在 in(),values() 时。该参数可选。 |
index | 在 list 和数组中, index 是元素的序号,在 map 中,index 是元素的 key,该参数可选。 |
注:Map 类型没有默认的 map,所以不能直接写 collection="map", 如果这么写,[email protected]("map") 注解。
有关参数的更详细内容,建议看:深入了解 MyBatis 参数
这节讲的是 foreach 中 map 的用法。
map 和 List,array 相比,map 是用 K,V 存储的,在 foreach 中,使用 map 时,index 属性值为 map 中的 Key 的值。
因为 map 中的 Key 不同于 list,array 中的索引,所以会有更丰富的用法。
第一个简单例子:
- <insert id="ins_string_string">
- insert into string_string (key, value) values
- <foreach item="item" index="key" collection="map"
- open="" separator="," close="">(#{key}, #{item})</foreach>
- </insert>
可以看到这个例子相当简单,表中需要两个值,正好和 K,V 对应,因而 map 中的一个 K,V 就对应一条数据,如果 map 中有多个 K,V,就会保存多个结果。
如果 map 中有两对 K,V,那么执行 SQL 如下:
大部分数据库是支持 values()() 这种形式的插入语句,可以插入多条 (相关链接 - 可能需 FQ)。
下面再看一个 select 的例子:
可以看到这里用 key=value 来作为查询条件,对于动态的查询,这种处理方式可以借鉴。一定要注意到 $ 和 #的区别,$ 的参数直接输出,# 的参数会被替换为?,然后传入参数值执行。
上述 SQL 执行日志如下:
最后,如果不考虑元素的顺序和 map 中 Key,map 和 list,array 可以拥有一样的效果,都是存储了多个值,然后循环读取出来。
foreach 一共有三种类型,分别为 List,[](array),Map 三种。
- <select id="countByUserList" resultType="_int" parameterType="list">
- select count(*) from users
- <where>
- id in
- <foreach item="item" collection="list" separator="," open="(" close=")" index="">
- #{item.id, jdbcType=NUMERIC}
- </foreach>
- </where>
- </select>
注:select count(*) from users WHERE id in (? , ?)
示例二:
- <select id="selectStorageProductInventroy" parameterType="java.util.Map" resultType="StorageProductInventroyModel">
- select op.inventroy_operation_id ,
- op.inventroy_id ,
- ty.name as operation_type,
- DATE_FORMAT(op.insert_time,'%Y/%m/%d') as insert_time,
- em.name as employee,
- sm1.name as from_store,
- st1.name as to_store,
- sm.name as from_storage,
- st.name as to_storage,
- hi.number,
- pr.name as product_name,
- pr.category_id as categoryString,
- pr.product_code,
- hi.amount,
- hi.back_amount,
- hi.unit,
- re.description as operation_reason,
- hi.description
- from inventroy_history hi left join inventroy_operation op
- on hi.inventroy_operation_id = op.inventroy_operation_id
- left join product pr
- on hi.product_id =pr.product_id
- left join operation_type ty
- on op.operation_type_id = ty.operation_type_id
- left join employee em
- on op.employee_id = em.employee_id
- left join (select inventroy_operation.to_storage_id as to_storage_id,storage.name as name
- from inventroy_operation , storage
- where inventroy_operation.to_storage_id = storage.storage_id) st
- on op.to_storage_id = st.to_storage_id
- left join (select inventroy_operation.from_storage_id as from_storage_id,storage.name as name
- from inventroy_operation , storage
- where inventroy_operation.from_storage_id = storage.storage_id) sm
- on op.from_storage_id = sm.from_storage_id
- left join (select inventroy_operation.to_store_id as to_store_id,store.name as name
- from inventroy_operation , store
- where inventroy_operation.to_store_id = store.store_id) st1
- on op.to_store_id = st1.to_store_id
- left join (select inventroy_operation.from_store_id as from_store_id,store.name as name
- from inventroy_operation , store
- where inventroy_operation.from_store_id = store.store_id) sm1
- on op.from_store_id = sm1.from_store_id
- left join operation_reason re
- on hi.operation_reason_id = re.operation_reason_id
- WHERE 1=1
- <if test="operation_type_id != null and operation_type_id.length != 0">
- and
- <foreach collection="operation_type_id" item="operationTypeId" index="index" open="(" separator="or" close=")">
- op.operation_type_id = #{operationTypeId}
- </foreach>
- </if>
- <if test="storage_id != 0 and storage_id != null">
- and (op.from_storage_id = #{storage_id} or op.to_storage_id = #{storage_id})
- </if>
- <if test="category_id != 0 and category_id != null">
- and pr.category_id like concat('%','(',#{category_id},')','%')
- </if>
- <if test="product_code != null">
- and pr.product_code like concat('%',#{product_code},'%')
- </if>
- <if test="product_name != null">
- and pr.name like concat('%',#{product_name},'%')
- </if>
- and date(op.insert_time) between #{start_time} and #{end_time}
- group by hi.inventroy_history_id
- </select>
注:and (op.operation_type_id = ? or op.operation_type_id = ?)
示例三:数组
- public void testQuery() {
- ColInfoDao dao=(ColInfoDao)ctx.getBean("colInfoDao");
- Map map = new HashMap();
- map.put("userId", "tom");
- map.put("password", "123");
- String[] a = { "20000001", "20000002" };
- map.put("classIds", Arrays.asList(a));
- Object password = dao.query(map);
- System.out.println("password:" + password);
- Assert.assertEquals("123", password);
- }
XML:(感觉不适合 mybatis,可以使用在 ibatis 中,iBatis 2.x 和 MyBatis 3.0.x)
- <select id="queryPasswordByUserId" parameterClass="java.util.Map" resultClass="java.lang.String">
- <![CDATA[
- select PASSWORD as password from T_S_P_USER
- ]]>
- <dynamic prepend="where">
- <isNotEmpty prepend="AND" property="userId">
- USER_ID=#userId#
- </isNotEmpty>
- <isNotEmpty prepend="AND" property="password">
- PASSWORD=#password#
- </isNotEmpty>
- <isNotEmpty prepend="AND" property="classIds">
- <iterate property="classIds" open="(" conjunction="OR" close=")">
- CLASS_ID = #classIds[]#
- </iterate>
- </isNotEmpty>
- </dynamic>
- </select>
示例四:Map
map 和 List,array 相比,map 是用 K,V 存储的,在 foreach 中,使用 map 时,index 属性值为 map 中的 Key 的值。
因为 map 中的 Key 不同于 list,array 中的索引,所以会有更丰富的用法。
- <insert id="ins_string_string">
- insert into string_string (key, value) values
- <foreach item="item" index="key" collection="map"
- open="" separator="," close="">(#{key}, #{item})</foreach>
- </insert>
可以看到这个例子相当简单,表中需要两个值,正好和 K,V 对应,因而 map 中的一个 K,V 就对应一条数据,如果 map 中有多个 K,V,就会保存多个结果。
如果 map 中有两对 K,V,那么执行 SQL 如下:
- DEBUG [main] - ==> Preparing: insert into string_string (key, value) values (?, ?) , (?, ?)
- DEBUG [main] - ==> Parameters: key 1(String), value 1(String), key 2(String), value 2(String)
- DEBUG [main] - <== Updates: 2
下面再看一个 select 的例子:
- <select id="sel_key_cols" resultType="int">
- select count(*) from key_cols where
- <foreach item="item" index="key" collection="map"
- open="" separator="AND" close="">${key} = #{item}</foreach>
- </select>
可以看到这里用 key=value 来作为查询条件,对于动态的查询,这种处理方式可以借鉴。一定要注意到 $ 和 #的区别,$ 的参数直接输出,# 的参数会被替换为?,然后传入参数值执行。
- DEBUG [main] - ==> Preparing: select count(*) from key_cols where col_a = ? AND col_b = ?
- DEBUG [main] - ==> Parameters: 22(Integer), 222(Integer)
- DEBUG [main] - <== Total: 1
最后,如果不考虑元素的顺序和 map 中 Key,map 和 list,array 可以拥有一样的效果,都是存储了多个值,然后循环读取出来。
mybatis 中 foreach 使用方法
来源: http://www.bubuko.com/infodetail-2279949.html