自定义mybatis插件

自定义mybatis插件,就是拦截mybatis框架指定的方法,然后对方法进行增强的过程,类似Spring的AOP。今天参考<mybatis从入门到精通>中的案例,定义一个对mybatis的map类型出参中的key从下划线转驼峰的插件,看看mybatis的插件是如何定义出来的
老规矩,先看目录

1、测试环境目录结构

projectName/
|src/
|—— test/
|     |——java/
|		 |——example/
|			|——plugin/
|				|—— CameHumpInterceptor.java
|		 |—— MapperTest.java
|	  |——resources/
|		|——mapper/
|			|——MapperTest.xml
|		|——mybatis/
|			|——mybatis-config.xml

解释一下各个类及文件的作用
CameHumpInterceptor.java:自定义的mybatis下划线转驼峰插件
MapperTest.java:测试类
MapperTest.xml:mybatis的mapper xml文件
mybatis-config.xml:mybatis的配置文件

2、编写测试的mapper文件

MapperTest.xml内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="example.MapperTest">
  <select id="selectTableNameMapById" resultType="java.util.Map">
        SELECT table_name,operate_type FROM testTable WHERE id = 1
  </select>
</mapper>

可以看到,这个statement的结果是一个Map类型。我们的任务就是将table_name以及operate_type这两个下划线的key改成驼峰,即:tableName和operateType。

3、定义mybatis插件,拦截mybatis出参

package example.plugin;

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

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

/**
 * 类 描 述:字段名,下划线转驼峰插件
 */
 //拦截的类和方法,除了ResultSetHandler.class,还有另外3个也可以拦截的类,可以自己查查用法
@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{
        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) {
        Set<String> keySet = new HashSet<String>(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(underlineToCamelhump(key), value);
            }
        }
    }

    private String underlineToCamelhump(String inputString) {
        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) {

    }
}

4、配置mybatis插件

从mybatis-config.xml中增加拦截器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

<!--配置mybatis插件。对mybatis的Map出参,key从下换线转成驼峰-->
    <plugins>
        <plugin interceptor="example.plugin.CameHumpInterceptor"></plugin>
    </plugins>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC">
                <property name="" value=""/>
            </transactionManager>
            <dataSource type="UNPOOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="111111"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/MapperTest.xml"/>
    </mappers>
</configuration>

5、测试类

public class MapperTest {
    private static SqlSessionFactory sqlSessionFactory;

    @BeforeClass
    public static void init(){
        try {
            Reader reader = Resources.getResourceAsReader("mybatis/mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testSelectAll(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //example.MapperTest是mapper文件的namespace,selectTableNameMapById是statement的id
        Map<String,String> map = sqlSession.selectOne("example.MapperTest.selectTableNameMapById");
        System.out.println(JSONObject.toJSONString(map));
    }
}

结果:

19:23:55.454 [main] DEBUG org.apache.ibatis.transaction.jdbc.JdbcTransaction - Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@6a84a97d]
19:23:55.489 [main] DEBUG example.MapperTest.selectTableNameMapById - ==>  Preparing: SELECT table_name,operate_type FROM testTable WHERE id = 1
19:23:55.549 [main] DEBUG example.MapperTest - ==> Parameters: 
19:23:55.603 [main] DEBUG example.MapperTest - <==      Total: 1
{"operateType":"UPDATE","tableName":"med_info_shop"}

可以看到map的key是operateTypetableName,已经从下划线转成了驼峰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值