相关文章推荐
英俊的桔子  ·  python ...·  1 年前    · 
咆哮的牛肉面  ·  基于多 WGCNA ...·  1 年前    · 

最近有个需求,就是使用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是将字段作为mapkey,字段对应的值作为map的值,sql查出一条数据可以,但是有多个结果集,就不能单纯用map来接收了,必须使用List来接收,循环然后map.get,封装成map,见下图,无疑这么操作很是恶心。 2.mybaits这么强大一个框架肯定邮箱对应的解决措施,在贵人的指导下,最终还是被我找到了解决措施。核心思想就是mybatis提供了一个名 在 MyBatisMapper 层编写查询方法,并希望以 Map 集合的形式接收返回结果时,如果直接使用 Map 作为返回值,并且期望 Map 的键具有某种特定的含义(比如行ID或特定列作为键),可能会遇到“@MapKey is required”的提示。因此,选择使用 Map 集合来接收每行的数据,其 Map 的键为列名,值为对应的列值。这意味着该表的字段(如列名、数据类型等)不是预定义的,而是根据表单的内容动态生成的。这样每个 Map 代表一行数据,Map 的键是列名,值是对应的数据。 项目需要从ibatis升级到MyBatis,dao有一个方法返回Map类型,具体是查询语句查询两个字段,将结果列表字段A的值作为key字段B的值作为value存入Map作为结果返回; ibatisDao继承SqlMapClientDaoSupport类的queryForMap(String statement, Object param, String key, String v... &lt;resultMap id="mapResultMap"   type="HashMap"&gt;   &lt;result property="key" column="key" jdbcType="VARCHAR" javaType="java.lang.String" /&gt; 1,用List&lt;Map&gt;接收,类似于List&lt;Bean&gt;(一条或多条记录)2,直接用Map接收(一条记录)Mapper (DAO)List&lt;Map&gt; getBybid(Integer bid);Mapper.xml&lt;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,