欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-31 23:08:28
...

背景:有些人在使用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());
        }
    }

测试结果

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