一、前言
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 configuration
PUBLIC "-//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究竟是如何分页的,后面再说