1. 问题描述
在web项目(SpringBoot)的开发过程中,有时候我们需要为一个返回的一个列表,做一些标记,比如是否可以删除标记,某某文件夹下面都有多少个文件等,这就要求我们添加一队映射关系(以文件夹的id作为key,以文件夹下面的文件个数作为value),当我们去数据库获取这种映射关系的时候并不能一下子就获取到,而是先返回一个只有两列数据的DTO,在去将DTO转化为键值对,添加到原来的List表。
2.问题解决
那么我们如何避免为了两列数据返回一个DTO,而直接生成一直键值对,然后去做相应的操作了。
- 重写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() {
}
}
- 如何在代码中使用
//先注入这个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();
- 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,完全没有意义、