知识回顾
上一篇 自定义MyBatis插件。我们实习了自定义插件,接下来我们先分析一下他的执行逻辑。
Plugin 实现了 InvocationHandler 接口,因此它的 invoke 方法会拦截所有的方法调用。invoke 方法会 对所拦截的方法进行检测,以决定是否执行插件逻辑。
我们看看 org.apache.ibatis.plugin.Plugin.java
public class Plugin implements InvocationHandler {private final Object target;private final Interceptor interceptor;private final Map<Class<?>, Set<Method>> signatureMap;private Plugin(Object target, Interceptor interceptor, Map<Class<?>, Set<Method>> signatureMap) {this.target = target;this.interceptor = interceptor;this.signatureMap = signatureMap;}public static Object wrap(Object target, Interceptor interceptor) {Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);Class<?> type = target.getClass();Class<?>[] interfaces = getAllInterfaces(type, signatureMap);return interfaces.length > 0 ? Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)) : target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {Set<Method> methods = (Set)this.signatureMap.get(method.getDeclaringClass());return methods != null && methods.contains(method) ? this.interceptor.intercept(new Invocation(this.target, method, args)) : method.invoke(this.target, args);} catch (Exception var5) {Exception e = var5;throw ExceptionUtil.unwrapThrowable(e);}}...
}
首先,invoke 方法会检测被拦截方法是否配置在插件的 @Signature 注解 中,若是,则执行插件逻辑,否则执行被拦截方法。插件逻辑封装在 org.apache.ibatis.plugin.Interceptor 的 intercept 方法中,该方法的参数类型为 Invocation ,主要用于存储目标类,方法以及方法参数列表。
public interface Interceptor {Object intercept(Invocation var1) throws Throwable;default Object plugin(Object target) {return Plugin.wrap(target, this);}default void setProperties(Properties properties) {}
}
分页插件分享
MyBatis 可以使用第三方的插件来对功能进行扩展,分⻚助手 PageHelper 就是其中一个非常优秀的插件。它将分⻚的复杂操作进行封装,使用简单的方式即可获得带分⻚的数据。
开发步骤:
-
导入通用 PageHelper 的坐标
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.1</version> </dependency> <dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>4.0</version> </dependency>
-
在 mybatis 核心配置文件中配置 PageHelper 插件并测试分⻚数据获取
配置文件
<!--注意:分⻚助手的插件 配置在通用馆mapper之前--> <plugin interceptor="com.github.pagehelper.PageHelper"> <!—指定方言 —><property name="dialect" value="mysql"/> </plugin>
测试:
@Testpublic void testPageHelper() {//设置分⻚参数// PageHelper.startPage(1, 2);List<User> select = userMapper.findAll();for (User user : select) {System.out.println(user);}}
没有分页的结果
Total: 4
User{id=1, username='lisi'}
User{id=2, username='tom'}
User{id=8, username='测试2'}
User{id=9, username='测试3'}
分页的结果
Total: 2
User{id=1, username='lisi'}
User{id=2, username='tom'}
分页实例代码
mybatis-pager-demo