前言:在上一篇博客中,我们讲到了mybatis的四种简单分页方式。分别是基于数组、Sql语句、分页插件和RowBounds的简单分页实现。不清楚的可以移步mybatis四种简单分页方式,这里详细讲解了几种分页方式的原理和优缺点,适合于初学者,很容易理解,不清楚的同学可以回去瞟上几眼。。
任务分析:当然,这并不是我们这篇博客讲解的重点。记得在上一篇中,我们只是实现了最简单的插件分页实现,还非常简陋,功能也还不够完善,日常使用起来也还不够简便。所以在这里,我们对插件分页的实现原理进行一下详细的介绍,并且实现一个功能完善的分页插件。
原理剖析:
//注解拦截器并且签名
@Intercepts(@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}))
和StatementHandler服务类中prepare方法相对应。
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException
自定义的插件类,都需要使用@Intercepts注解,@Signature是对插件需要拦截的对象进行签名,type表示要拦截的类型,method表示拦截类中的方法,args是需要的参数,这里的参数在后面也可以获取到。
StatementHandler:数据库会话器,专门用于处理数据库会话,statement的执行操作,是一个接口。
MetaObject:mybatis工具类,可以有效的读取或修改一些重要对象的属性,基本思想是通过反射去获取和设置对象的属性值,只是MetaObject类不需要我们自己去实现具体反射的方法,已经封装好了。
通过MetaObject.getValue()和MetaObject.setValue(name,value)方法去获取对象属性值和设置对象属性值。
通过MetaObject属性的获取流程:
MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement")
上面代码是怎么获取到MappedStatement对象的??这里的metaStatementHandler是一个MetaObject对象。
首先通过metaStatementHandler.getValue(“delegate”)拿到真正实现StatementHandler接口的服务对象。
public class RoutingStatementHandler implements StatementHandler {
//delegate属性来自这里,是一个实现了StatementHandler接口的类
private final StatementHandler delegate;
//通过这里给delegate属性赋值
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
switch(RoutingStatementHandler.SyntheticClass_1.$SwitchMap$org$apache$ibatis$mapping$StatementType[ms.getStatementType().ordinal()]) {
case 1:
this.delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case 2:
this.delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case 3:
this.delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
}
}
}
拿到具体的服务对象(处理逻辑的StatementHandler实现类)后,再获取mappedStatement属性,我们再来看mappedStatement属性的定义:
public abstract class BaseStatementHandler implements StatementHandler {
protected final Configuration configuration;
protected final ObjectFactory objectFactory;
protected final TypeHandlerRegistry typeHandlerRegistry;
protected final ResultSetHandler resultSetHandler;
protected final ParameterHandler parameterHandler;
protected final Executo