Mybatis之插件开发之下划线转驼峰形式插件

背景:有些人在使用Mybatis时,为了方便扩展而使用Map类型的返回值。使用Map作为返回值时,Map中的键值就是查询结果中的列名,而列名一般都是大小写字母或者下划线形式,因此和Java使用的驼峰形式不一致,而且由于不同数据库查询出来的大小写也不一致,因此为了保证在使用Map是属性一致,可以对Map类型结果进行特殊处理,即不同格式的列名转换为Java的驼峰形式命名。这种情况下我们可以使用拦截器,通过拦截ResultSetHander接口中的handleResultSets方法去处理Map类型的结果,拦截器代码如下:

1,拦截器类CameHumpInterceptor.class

package person.david.ssm.interceptor;

import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;

import java.sql.Statement;
import java.util.*;

/**
 * @author David
 * @className CameHumpInterceptor
 * Mybatis Map 类型下划线key转小写驼峰形式
 * @date 2020/2/13 20:40
 */
@Intercepts(
        @Signature(
                type = ResultSetHandler.class,
                method = "handleResultSets",
                args = {Statement.class})

)
@SuppressWarnings({"unchecked","rawtypes"})
public class CameHumpInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("==================>开始进行拦截...");
        List<Object> list = (List<Object>)invocation.proceed();
        for (Object object : list) {
            //如果结果是Map类型,就对Map的key进行转换
            if (object instanceof Map){
                processMap((Map) object);
            }else {
                break;
            }
        }
        return list;
    }

    /**
     * 处理map类型
     *
     * @param map
     */
    private void processMap(Map<String,Object> map){
        System.out.println("==================>开始处理map类型...");

        Set<String> keySet = new HashSet<>(map.keySet());
        for (String key : keySet) {
            //以大写开头的字母为小写,如果包含下划线也会处理为驼峰
            //此处只通过简单的两个标识来判断
            if ((key.charAt(0) >= 'A' && key.charAt(0) <= 'Z') || key.indexOf("_") >= 0 ){
                Object value = map.get(key);
                map.remove(key);
                map.put(underlineToCamehunp(key),value);
            }
        }
    }


    /**
     * 将下划线风格转换为驼峰风格
     * @param inputString
     * @return
     */
    public static String underlineToCamehunp(String inputString){
        System.out.println("==================>开始进行转换...");
        StringBuilder sb = new StringBuilder();
        boolean nextUppercase = false;
        for (int i = 0; i < inputString.length(); i++) {
            char c = inputString.charAt(i);
            if (c == '_') {
                if (sb.length()>0) {
                    nextUppercase = true;
                }
            }else {
                if (nextUppercase) {
                    sb.append(Character.toUpperCase(c));
                    nextUppercase = false;
                }else {
                    sb.append(Character.toLowerCase(c));
                }
            }
        }

        return sb.toString();
    }


    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target,this);
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

2,接口TestMapper.class

@CacheNamespace(eviction = FifoCache.class,flushInterval = 60000,size = 512,readWrite = true)
public interface TestMapper {
   
    Map<Object,Object> selectStuById(int id);
}

3,TestMapper.xml文件

	<select id="selectStuById" parameterType="int" resultType="map">
        select stu_name, stu_age, stu_gender, stu_hobby
        from t_test
        where id = #{id}
    </select>

4,配置文件里配置写好的拦截器插件

<!--配置下划线风格转换驼峰风格的拦截器插件-->
    <plugins>
        <plugin interceptor="person.david.ssm.interceptor.CameHumpInterceptor"/>
    </plugins>

5,测试类测试下划线转驼峰

	@Test
    public void test7(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        TestMapper testMapper = sqlSession.getMapper(TestMapper.class);
        Map<Object ,Object> map = testMapper.selectStuById(4);
        for (Map.Entry<Object, Object> entry : map.entrySet()) {
            System.out.println(entry.getKey()+"=========>"+entry.getValue());
        }
    }

测试结果

在这里插入图片描述

发布了72 篇原创文章 · 获赞 21 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_39513430/article/details/104326996