- Executor
- ParameterHandler
- ResultSetHandler
-
8.1 拦截器接口介绍
public interface Interceptor {
Object intercept(Invocation var1) throws Throwable;
Object plugin(Object target);
void setProperties(Properties var1);
}
setProperties
用来传递插件的参数,可以通过参数来改变插件的行为
参数值传递:<plugins>
<plugin interceptor="com.ql.simple.plugin.***INterceptor">
<property name="prop1" value="value1"/>
<property name="prop2" value="value2"/>
</plugin>
</plugins>
plugin
方法参数target就要拦截器要拦截的对象,该方法会在创建被拦截的接口实现类时被调用,只需要调用MyBatis提供的Plugin类的wrap静态方法就可以通过java的动态代理拦截目标对象@Overrride
public Object plugin(Object target){
return Plugin.wrap(target, this);
}
wrap
方法会自动判断拦截器的前面和被拦截器对象的接口是否匹配,只有匹配的情况下才会使用动态代理拦截目标对象,因此上面不用做额外的逻辑判断
intercept
是MyBatis运行时要执行的拦截方法:
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget();
Method method = invocation.getMethod();
Object[] args = invocation.getArgs();
Object result = invocation.proceed();
return result;
}
invocation.proceed();
执行被拦截对象真正的方法
8.2 拦截器签名介绍
@Intercepts
@Signature
用来配置拦截器要拦截的接口的方法
@Intercepts({
@Signature(
type = ResultSetHandler.class,
method = "handleResultSets",
args = {Statement.class})
})
public class DemoInterceptor implements Interceptor {
8.2.1 Executor接口
- update
- query
- queryCursor
- flushStatements
- commit
- rollback
- getTransaction
- close
-
8.2.2 ParameterHandler
8.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 o : list) {
// 如果结果是Map类型,就对Map的key进行转换
if (o instanceof Map) {
processMap((Map) o);
}else {
break;
}
}
return list;
}
private void processMap(Map<String, Object> map) {
Set<String> keySet = new HashSet<>(map.keySet());
for (String key : keySet) {
// 将以大写开头的字符串转换为小写,如果包含下划线也会处理为驼峰
// 此处只通过这两个简单的表示来判断是否进行转换
if ((key.charAt(0) >= 'A' && key.indexOf(0) <= 'Z') || key.indexOf("_") >= 0){
Object value = map.get(key);
map.remove(key);
map.put(underlineToCamelhump(key), value);
}
}
}
public static String underlineToCamelhump(String inputString){
StringBuffer sb = new StringBuffer();
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 o) {
return Plugin.wrap(o, this);
}
@Override
public void setProperties(Properties properties) {
}
}
8.4 分页插件