org.apache.ibatis.binding.MapperMethod中execute方法
...
} else if (method.returnsMap()) { result = executeForMap(sqlSession, args); } else {
...
private <K, V> Map<K, V> executeForMap(SqlSession sqlSession, Object[] args) { Map<K, V> result; Object param = method.convertArgsToSqlCommandParam(args); if (method.hasRowBounds()) { RowBounds rowBounds = method.extractRowBounds(args); result = sqlSession.<K, V>selectMap(command.getName(), param, method.getMapKey(), rowBounds); } else { result = sqlSession.<K, V>selectMap(command.getName(), param, method.getMapKey()); } return result; }
映射為map時有個可自定義的參數:mapkey
private String getMapKey(Method method) { String mapKey = null; if (Map.class.isAssignableFrom(method.getReturnType())) { final MapKey mapKeyAnnotation = method.getAnnotation(MapKey.class); if (mapKeyAnnotation != null) { mapKey = mapKeyAnnotation.value(); } } return mapKey; }
通過org.apache.ibatis.annotations.MapKey可以配置該參數,該參數應與sql中select的字段一致且為大寫。
最終的resultHandler:
public class DefaultMapResultHandler<K, V> implements ResultHandler { private final Map<K, V> mappedResults; private final String mapKey; private final ObjectFactory objectFactory; private final ObjectWrapperFactory objectWrapperFactory; @SuppressWarnings("unchecked") public DefaultMapResultHandler(String mapKey, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) { this.objectFactory = objectFactory; this.objectWrapperFactory = objectWrapperFactory; this.mappedResults = objectFactory.create(Map.class); this.mapKey = mapKey; } public void handleResult(ResultContext context) { // TODO is that assignment always true? final V value = (V) context.getResultObject(); final MetaObject mo = MetaObject.forObject(value, objectFactory, objectWrapperFactory); // TODO is that assignment always true? final K key = (K) mo.getValue(mapKey); mappedResults.put(key, value); } public Map<K, V> getMappedResults() { return mappedResults; } }