1. 问题描述

  在web项目(SpringBoot)的开发过程中,有时候我们需要为一个返回的一个列表,做一些标记,比如是否可以删除标记,某某文件夹下面都有多少个文件等,这就要求我们添加一队映射关系(以文件夹的id作为key,以文件夹下面的文件个数作为value),当我们去数据库获取这种映射关系的时候并不能一下子就获取到,而是先返回一个只有两列数据的DTO,在去将DTO转化为键值对,添加到原来的List表。

2.问题解决

 那么我们如何避免为了两列数据返回一个DTO,而直接生成一直键值对,然后去做相应的操作了。

  1. 重写ResultHandler方法
import java.util.HashMap;
import java.util.Map;

import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.stereotype.Component;

/** * 描述:将有来有两个返回值且需要将其中一个作为key一个作为value返回的hander * * @since 2019年5月21日 下午8:13:50 * @author xh */
@Component
@SuppressWarnings({ "unchecked", "rawtypes" })
public class ResultHander implements ResultHandler {

    private final Map mapResults = new HashMap();
    //根据需要,这两个字段是可以改变的,这里用String基本可以符合所有需求
    private String key;

    private String value;

    /** * 映射结果集 */
    @Override
    public void handleResult(ResultContext context) {

        // 组装ley-value
        Map map = (Map) context.getResultObject();

        // 将查询放入结果集
        mapResults.put(map.get(key), map.get(value));
    }

    /** * 返回映射 * * @return 结果 */
    public Map getMapResults() {
        return mapResults;
    }

    /** * @param key * key * @param value * value */
    public ResultHander(String key, String value) {
        this.key = key;
        this.value = value;
    }

    /** * 空构造 */
    public ResultHander() {
    }
}
  1. 如何在代码中使用
	//先注入这个MyBatis的sqlSession,包名:org.apache.ibatis.session.SqlSession
 	 @Autowired
    private SqlSession sqlSession;
		
		//MyBatis的XML文件查询条件,直接用map,有几个条件map里面放几个,其中map的key相当于dao层中@Param里面的内容,也就是说用了这个时候不需要写dao层。
		HashMap<String, Object> param = new HashMap<>();

        // 快速获取hashMap写法(xml的mysql查询条件吗,多条件直接往里面put)
        param.put("sList", spaceIdList);

        // 填写键值对(xml文件中mysql的返回值,前面一个作为返回map的key后面的作为value)
        ResultHander hander = new ResultHander("spaceId", "wkdocNum");

        // 原mybatis自定义返回值查询(全限定方法名,带上mybatis的namespace,getWkDocAmountDao为xml文件中查询语句的id)
        sqlSession.select("com...getWkDocAmountDao", param, hander);
		//返回映射好的键值对。可以用键值对做想做的操作
        Map<?, ?> result = hander.getMapResults();
  1. XML文件的写法(如何查询)
<--返回值映射-->
<resultMap id="spaceNumResult" type="java.util.HashMap">
        <result property="spaceId" column="space_id" javaType="java.lang.Long" jdbcType="BIGINT" />
        <result property="wkdocNum" column="wkdoc_num" javaType="java.lang.Integer" jdbcType="INTEGER" />
</resultMap>


    <!--获取空间下面的文档个数spaec_id作为key,wkdoc_num作为value,返回map -->
    <select id="getWkDocAmountDao" parameterType="java.lang.Long" resultMap="spaceNumResult">
        SELECT
        COUNT( A.space_id ) AS wkdoc_num,
        space_id
        FROM
        <include refid="wkdoc"></include>
        A
        WHERE
        A.space_id IN
        <foreach collection="sList" item="s" index="index" open="(" separator="," close=")">
            #{s,jdbcType=BIGINT}
        </foreach>
        GROUP BY
        A.space_id
    </select>

以上即是直接获取键值对的写法,另外

  如果我们在MyBatis的dao层方法上加上注解@MapKey,也是可以实现的,但这样的后果是,只能返回一条结果,其中的一个作为主键,其他的全部都作为value,完全没有意义、