最近有个需求,就是使用mybatis时,向mysql中插入数据,其参数为map类型,map里面的key为列名,而key对应的value是该列对应的列值;问题是每次插入mysql中数据行的部分列,即map里面key的值每次都不固定,在用mybatis时需要通过map的key作为列名。
对于这类问题基本思路就是用foreach标签遍历map,因此需要看看foreach的知识。
foreach属性
属性 描述
item
|
循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details。
具体说明:若collection属性为list或array,则item代表list或array里面的一个元素。若collection属性对应一个map,则item代表的是map中的value集合中的单个value
该参数为必选。
|
collection
|
foreach遍历的对象,作为入参时,List对象默认用list代替作为键,数组对象有array代替作为键,Map对象没有默认的键。也就是传入的集合(list,array,map)的名字,这个名字可以在foreach里面随便引用)
当然在作为入参时可以使用@Param(“params”)来设置键,设置keyName后,list,array将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
如果User有属性List ids。入参是User对象,那么这个collection = “ids”
如果User有属性Ids ids;其中Ids是个对象,Ids有个属性List id;入参是User对象,那么collection = “ids.id”
如果传入参数类型为map,这个入参有注解@Param(“params”),则map的所有的key集合可以写成params.keys,所有值集合可以写成params.values。这样foreach就可以对key集合或值集合进行迭代了。
上面只是举例,具体collection等于什么,就看你想对那个元素做循环。
该参数为必选。
|
separator
|
元素之间的分隔符,例如在in()的时候,separator=”,”会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
|
open
|
foreach代码的开始符号,一般是(和close=”)”合用。常用在in(),values()时。该参数可选。
|
close
|
foreach代码的关闭符号,一般是)和open=”(“合用。常用在in(),values()时。该参数可选。
|
index
|
在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
|
有了以上基础就可以实现我们想要的功能:
首先,在mapper对应的dao中使用@param注解,显式指定集合参数类的别名(列表和数组有默认的别名list和array):
public interface CrawDao {
public void saveNewNews(@Param(“params”)Map<String, String> params);
第二步,在mapper的xml文件里对map的key进行迭代:
<?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=“us.codecraft.webmagic.dao.CrawDao”>
<insert id=“saveNewNews” parameterType=“java.util.Map”>
insert ignore into tb_news
<foreach collection=“params.keys” item=“key” open=“(“ close=“)” separator=“,” >
${key}
</foreach>
values
<foreach collection=“params.keys” item=“key” open=“(“ close=“)” separator=“,”>
#{params[${key}]}
</foreach>
</insert>
</mapper>
通过以上两步就动态的获取了列名,并对对应的列赋值。
1.有时候我们想将mybatis查出来的数据封装到一个map中,从而循环list根据id直接从map中取值。但是mybatis默认封装的map是将字段作为map的key,字段对应的值作为map的值,sql查出一条数据可以,但是有多个结果集,就不能单纯用map来接收了,必须使用List来接收,循环然后map.get,封装成map,见下图,无疑这么操作很是恶心。
2.mybaits这么强大一个框架肯定邮箱对应的解决措施,在贵人的指导下,最终还是被我找到了解决措施。核心思想就是mybatis提供了一个名
在 MyBatis 的 Mapper 层编写查询方法,并希望以 Map 集合的形式接收返回结果时,如果直接使用 Map 作为返回值,并且期望 Map 的键具有某种特定的含义(比如行ID或特定列作为键),可能会遇到“@MapKey is required”的提示。因此,选择使用 Map 集合来接收每行的数据,其中 Map 的键为列名,值为对应的列值。这意味着该表的字段(如列名、数据类型等)不是预定义的,而是根据表单的内容动态生成的。这样每个 Map 代表一行数据,Map 的键是列名,值是对应的数据。
项目需要从ibatis升级到MyBatis,dao中有一个方法返回Map类型,具体是查询语句查询两个字段,将结果列表字段A的值作为key字段B的值作为value存入Map中作为结果返回;
ibatis中Dao继承SqlMapClientDaoSupport类的queryForMap(String statement, Object param, String key, String v...
<resultMap id="mapResultMap" type="HashMap">
<result property="key" column="key" jdbcType="VARCHAR" javaType="java.lang.String" />
1,用List<Map>接收,类似于List<Bean>(一条或多条记录)2,直接用Map接收(一条记录)Mapper (DAO)List<Map> getBybid(Integer bid);Mapper.xml<select id="getBybid" resultType="java.util.Map" parameterType="Integer&quo
int updateByBatch(@Param("content") Map alreadySoldNumMap); mapper
update COUPON_CATEGORY
public interface CrawDao {
public void saveNewNews(@Param("params")Map<String, String> params);
mybatis查询结果为map时,出来的结果默认是下面这样的[{key: 1,value: 'xx'},{key: 2,value: 'xxx'}]我们想要的是这样的:{1 : 'xx',2 : 'xxx'}如果自己转换的话非常麻烦。经过一番查找,发现mybatis可以在查询出来的时候通过修改handler自动转换先写一个Handler继承ResultHandlerpackage;import o...
public class MapKeyLowerWrapper extends MapWrapper {
public MapKeyLowerWrapper(MetaObject metaObject, Map<String, Object> map) {
super(metaObject,