mybatis分页思想:
当查询的数据量很大时需要分页显示,然而不同的数据库分页查询也不同; mybatis采取的策略就是在查询数据时,拦截查询语句,根据不同的数据库对原始查询语句进行修改,变成数据库对应的分页查询语句;
mybatis就是对jdbc的进一步封装,在弄清楚mybatis分页查询之前我们先想一想jdbc分页怎么实现的,这样可能会有事半功倍的效果!!!
正常的jdbc查询:
1.创建connection对象
2.创建Statement对象或者PreparedStatement对象
3.Statement对象或者PreparedStatement对象执行查询分页查询sql
4.得到ResultSet结果
mybatis分页的具体实现:
通过自定义拦截器,在执行分布查询之前修改sql语句;即:拦截StatementHandler接口实现类的prepare方法,在对sql进行修改后执行prepare方法;
通过debug得出步骤:
1.创建RoutingStatementHandler对象
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
switch (ms.getStatementType()) {
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
}
}
通过代码可以得知根据ms.getStatementType()初始化delegate对象,delegate对象也是StatementHandler类型
2.进入到自定义的拦截方法(这里主要写我们拦截的目的即修改sql语句)
3.调用prepare方法,即 RoutingStatementHandler对象的prepare方法;
public Statement prepare(Connection connection) throws SQLException {
return delegate.prepare(connection);
}
也就是调用delegate.prepare(connection),而delegate具体是哪一个StatementHandler的实现类呢,通过初始化RoutingStatementHandler对象已经得知
从源代码可以看出RoutingStatementHandler类就是一个包装类,对delegate方法进一步包装
RoutingStatementHandler对象是干什么的(个人理解,不对之处请批评指正)?
首先想一下mybatis对数据库的操作,是不是一个Dao接口与一个XML与之对应(至于怎么对应之前有过讲解的一篇文章),
但是xml封装语句里面有一些语句可能是Statement的有一些可能是PreparedStatemen,不同的语句要用不同的Statement去执行,所以RoutingStatementHandler对象应运而生;
他就是一个跑龙套的封装类,因为他自己本身什么也没有干,都是调用的delegate方法;创建RoutingStatementHandler对象时通过MappedStatement初始化具体干活的delegate;
网友评论