MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现

发布时间:2017-2-25 12:35:59 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现 ",主要涉及到MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现 方面的内容,对于MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现 感兴趣的同学可以参考一下。

1. 问题描述

  在使用MyBatis,我们经常会遇到这种情况:SELECT两个字段,需要返回一个Map,其中第一个字段作为key,第二个字段作为value。MyBatis的MapKey虽然很实用,但并不能解决这种场景。这里,就介绍一种使用拦截器来解决这个问题的方案。

2. 解决方案

源码详见:spring-mybatis-test

2.1 注解

package com.adu.spring_test.mybatis.annotations;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 将查询结果映射成map的注解,其中第一个字段为key,第二个字段为value. * <p> * 注:返回类型必须为{@link java.util.Map Map<K, V>}。K/V的类型通过MyBatis的TypeHander进行类型转换,如有必要可自定义TypeHander。 * * @author yunjie.du * @date 2016/12/22 18:44 */@[email protected](RetentionPolicy.RUNTIME)@Target({ ElementType.METHOD })public @interface MapF2F {}

2.2 拦截器

package com.adu.spring_test.mybatis.interceptor;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Properties;import org.apache.commons.lang3.StringUtils;import org.apache.ibatis.executor.resultset.DefaultResultSetHandler;import org.apache.ibatis.executor.resultset.ResultSetHandler;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Plugin;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.type.TypeHandler;import org.apache.ibatis.type.TypeHandlerRegistry;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.adu.spring_test.mybatis.annotations.MapF2F;import com.adu.spring_test.mybatis.util.ReflectUtil;import javafx.util.Pair;/** * MapF2F的拦截器 *  * @author yunjie.du * @date 2016/12/22 18:44 */@Intercepts(@Signature(method = "handleResultSets", type = ResultSetHandler.class, args = { Statement.class }))public class MapInterceptor implements Interceptor {    private Logger logger = LoggerFactory.getLogger(MapInterceptor.class);    @Override    public Object intercept(Invocation invocation) throws Throwable {        Object target = invocation.getTarget();        if (target instanceof DefaultResultSetHandler) {            DefaultResultSetHandler defaultResultSetHandler = (DefaultResultSetHandler) target;            MappedStatement mappedStatement = ReflectUtil.getFieldValue(defaultResultSetHandler, "mappedStatement");            String className = StringUtils.substringBeforeLast(mappedStatement.getId(), ".");// 当前类            String currentMethodName = StringUtils.substringAfterLast(mappedStatement.getId(), ".");// 当前方法            Method method = findMethod(className, currentMethodName);// 获取当前Method            if (method == null || method.getAnnotation(MapF2F.class) == null) {// 如果当前Method没有注解MapF2F                return invocation.proceed();            }            // 如果有MapF2F注解,则这里对结果进行拦截并转换            Statement statement = (Statement) invocation.getArgs()[0];            Pair<Class<?>, Class<?>> kvTypePair = getKVTypeOfReturnMap(method);// 获取返回Map里key-value的类型            TypeHandlerRegistry typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();// 获取各种TypeHander的注册器            return result2Map(statement, typeHandlerRegistry, kvTypePair);        }        return invocation.proceed();    }    @Override    public Object plugin(Object obj) {        return Plugin.wrap(obj, this);    }    @Override    public void setProperties(Properties properties) {    }    /**     * 找到与指定函数名匹配的Method。     *      * @param className     * @param targetMethodName     * @return     * @throws Throwable     */    private Method findMethod(String className, String targetMethodName) throws Throwable {        Method[] methods = Class.forName(className).getDeclaredMethods();// 该类所有声明的方法        if (methods == null) {            return null;        }        for (Method method : methods) {            if (StringUtils.equals(method.getName(), targetMethodName)) {                return method;            }

上一篇:使用Maven私服的好处
下一篇:centos6 系统安装 system-config

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。