Mybatis拦截器使用实例_下面线键值转小写驼峰形式插件
使用 Map 作为返回值时, Map 中的键值就是查询结果中的列名 ,而列名一般都是大小写字母或者下画线形式,和 Java中使用的驼峰形式不一致。而且由于不同数据库查询结果列的大小写也并不一致,因此为了保证在使用 Map 时的属性一致,可以对 Map 类型的结果进行特殊处理,即将不同格式的列名转换为Java 中的驼峰形式。这种情况下,我们就可以使用拦截器,通过拦截 ResultSetHandler接口中的 handleResultSets 方法去处理 Map 类型的结果。拦截器实现代码如下。
@Intercepts( @Signature( type = ResultSetHandler.class , method = "handlerResultSets" , args = {Statement.class} ) ) 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类型 * */ 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){ //取出原value值 Object value = map.get(key); //将原key值去掉 map.remove(key); //将转换好的key重新放入map中 map.put(underlineToCamelhump(key) , value); } } } /* * 将下画线风格替换为驼峰风格 * */ public static 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){ ////这时"_"在中间,需要对其后第一个字符进行大写处理,将标志修改为true nextUpperCase = true; } }else { if(nextUpperCase){ //接上面,"_"后第一个字符进行大写处理,标志修改为false sb.append(Character.toUpperCase(c)); nextUpperCase = false; }else{ //这里用于处理其他不需要特殊对待的字符,正常输出即可。 sb.append(Character.toLowerCase(c)); } } } return sb.toString(); } /* * target:拦截对象 * * */ @Override public Object plugin(Object target){ // 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数 return (target instanceof RoutingStatementHandler)? Plugin.wrap(target,this):target; } //实现插件参数传递 @Override public void setProperties(Properties properties){ } }
想要使用该插件,需要在 mybatis_config.xml中配置该插件。
<plugins> <plugin interceptor="com.example.simple.plugin.CameHumpinterceptor"></plugin> </plugins>
在上面拦截器代码执行中,invocation.proceed ()执行的结果被强制转换为了 List 类型,这是因为拦截器接口 ResultSetHandler 的handleResultSets 方法的返回值为 List 类型,所以
才能在这里直接强制转换,如果不知道这一点,就很难处理这个返回值,许多接口方法的返回值类型都是 List ,但是还有很多其他的类型,所以在写拦截器时,要根据被拦截的方法来确
定返回值的类型。