一、前言
Mybatis支持插件实现接口 org.apache.ibatis.plugin.Interceptor 来达到插件的功能,最常见的插件就是分页插件。
引入插件 pagehelper
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.2</version></dependency>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><settings><setting name="logImpl" value="STDOUT_LOGGING" /><setting name="mapUnderscoreToCamelCase" value="true"/></settings><!--配置PageHelper分页插件拦截器--><plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="offsetAsPageNum" value="true"/><property name="helperDialect" value="mysql"/><property name="rowBoundsWithCount" value="true"/><property name="reasonable" value="true"/></plugin></plugins><environments default="mysql"><environment id="mysql"><!-- 配置事务--><transactionManager type="JDBC"></transactionManager><!-- 配置连接池--><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/smiler_user?useUnicode=true&characterEncoding=utf8"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!-- 配置映射文件的位置--><mappers><!-- <mapper resource="user/mapper/UserMapper.xml"></mapper>--><!-- 用于指定dao接口所在的包,指定之后就不再需要写,mapper resources class mapper.xml--><package name="user.mapper"/></mappers></configuration>
public static void main(String[] args) throws IOException {InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(in);SqlSession session = factory.openSession();//获得dao 的代理对象PageHelper.startPage(0,2);UserMapper userMapper = session.getMapper(UserMapper.class);List<User> user = userMapper.queryByName("king");PageHelper.clearPage();// User user2 = userMapper.queryById(21);System.out.println(user.toString());// userMapper.deleteById("1");// userMapper.deleteByName("'dasd' or 1=1");session.commit();}
二、源码分析
1、doQuery
在org.apache.ibatis.executor.SimpleExecutor#doQuery 方法执行的时候,会使用configuration.newStatementHandler 来生成一个StatementHandler。
2、configuration.newStatementHandler
在 newStatementHandler 方法中,会使用拦截器来生成新的statementHandler,假如使用了分页插件,则会对sql进行重写。

InterceptorChain使用到了责任链模式:https://www.yuque.com/wangchao-volk4/udv4ny/rlz4pm
3、Interceptor
�PageHelper就是实现了这个接口 org.apache.ibatis.plugin.Interceptor
关于pageHelper究竟是如何分页的,后面再说

