1. 需求描述
平时主要负责聚合公司各组的数据到ES,经常会遇到从不同的表取出两列简单的映射关系的需求(就像是只需要学生表的学号和姓名),开始根据其他人流传下来的代码风格,查询返回一个List,然后自己写代码遍历映射成Map,大量重复的无效率的工作实在是不堪其扰,抽空找了找资料发现可以通过Mybatis支持自定义 ResultHandler 来处理,总算是看着代码舒服多了。
2. 解决方案
2.1 Mbatis 映射
首先将 Mybatis 的 Sql 配置返回值类型为 Map
<select id="***" resultType="java.util.Map" parameterType="*"> select column_1, column_2 from table </select>
2.2 创建ResultHandler
为了通用性,使用泛型指定返回的映射字段类型
import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import java.util.HashMap; import java.util.Map; /** * 处理简单的两个基本属性之间的映射关系 * @author * @version 1.0 * @date */ public class TwoColumnsMapResultHandler<K, V> implements ResultHandler<Map<String, Object>> { private final Map<K, V> resultMap = new HashMap<>(); private final String keyColumn; private final String valueColumn; public TwoColumnsMapResultHandler(String keyColumn, String valueColumn) { this.keyColumn = keyColumn; this.valueColumn = valueColumn; } @Override @SuppressWarnings("unchecked") public void handleResult(ResultContext<? extends Map<String, Object>> resultContext) { Map<String, Object> result = resultContext.getResultObject(); if (result.get(keyColumn) != null) { resultMap.put((K) result.get(keyColumn), (V) result.get(valueColumn)); } } public Map<K, V> getResults() { return resultMap; } }
2.3 使用自定义的ResultHandler
public Map<String, String> selectExample(SqlSession session, SqlQueryParam param) throws SqlQueryException { TwoColumnsMapResultHandler<String, String> handler = new TwoColumnsMapResultHandler<>("column_1", "column_2"); try { session.select("***", param, handler); return handler.getResults(); } catch (Exception e) { throw new SqlQueryException(e); } }