PageMybatisInterceptor 的原理
来源:互联网 发布:网络问卷调查赚钱 编辑:程序博客网 时间:2024/04/29 20:56
首先 要知道,所有的拦截器都是需要配置的,这里拦截器是在执行 mapper 的方法的时候,执行的。<bean name="paginationInterceptor" class="com.common.mvc.mybatis.PageMybatisInterceptor"></bean><!--Session Factory--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations"> <list> <value>classpath:mapper/*/*.xml</value> <value>classpath:mybatis/mapping/*.xml</value> </list> </property> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageHelper"> <property name="properties"> <value> dialect=mysql pageSizeZero=true reasonable=true </value> </property> </bean> <ref bean="paginationInterceptor" /> </array> </property></bean>通过这个配置,在服务器启动的时候,会生成一个映射(key=mapper 的方法名,value=拦截器列表)这样 ,在某个服务内,调用mapper方法的时候,都会调用 拦截器的intercept()方法。我们的拦截器:public class PageMybatisInterceptor implements Interceptor { private static final Logger logger = LoggerFactory.getLogger(PageMybatisInterceptor.class); public static final ThreadLocal<Page> localPage = new ThreadLocal<Page>(); /** * 开始分页 * @param pageNum * @param pageSize */ public static void startPage(Integer pageNum, Integer pageSize) { if(pageNum==null) pageNum = Page.DEFAULT_PAGE_NUM; if(pageSize==null) pageSize = Page.DEFAULT_PAGE_SIZE; localPage.set(new Page(pageNum, pageSize)); } /** * 结束分页并返回结果,该方法必须被调用,否则localPage会一直保存下去,直到下一次startPage * @return */ public static Page endPage() { Page page = localPage.get(); localPage.remove(); return page; } @Override public Object intercept(Invocation invocation) throws Throwable { if (localPage.get() == null) { return invocation.proceed(); } if (invocation.getTarget() instanceof StatementHandler) { StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler); // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环 // 可以分离出最原始的的目标类) while (metaStatementHandler.hasGetter("h")) { Object object = metaStatementHandler.getValue("h"); metaStatementHandler = SystemMetaObject.forObject(object); } // 分离最后一个代理对象的目标类 while (metaStatementHandler.hasGetter("target")) { Object object = metaStatementHandler.getValue("target"); metaStatementHandler = SystemMetaObject.forObject(object); } MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); //分页信息if (localPage.get() != null) { Page page = localPage.get(); BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql"); // 分页参数作为参数对象parameterObject的一个属性 String sql = boundSql.getSql(); // 重写sql String pageSql = buildPageSql(sql, page); //重写分页sql metaStatementHandler.setValue("delegate.boundSql.sql", pageSql); Connection connection = (Connection) invocation.getArgs()[0]; // 重设分页参数里的总页数等 setPageParameter(sql, connection, mappedStatement, boundSql, page); // 将执行权交给下一个拦截器 return invocation.proceed(); } else if (invocation.getTarget() instanceof ResultSetHandler) { Object result = invocation.proceed(); Page page = localPage.get(); page.setResult((List) result); return result; } return null; }可以 想一下,如果在调用mapper 之前调用 PageMybatisInterceptor.startPage(pageNum, pageSize);就会存在一个ThreadLocal 对象,并且 里面存储了 pagenum 和pagesize这样在调用 intercept ()方法的时候,先判断 是否存在 threadLocal ,如果不存在,就不用 添加切面,如果存在 就先更改语句,在调用mapper。
0 0
- PageMybatisInterceptor 的原理
- 数字证书的工作原理(加密原理)
- DNS劫持原理、DNS 污染的原理
- 搜索引擎算法原理 百度算法的原理 [
- 舵机的相关原理与控制原理
- quagga 的原理解析 zebra原理解析
- 照相机成像原理 数码相机的成像原理
- javascript原理系列— new的原理
- 栈的原理和缓冲区溢出原理
- quagga 的原理解析 zebra原理解析
- RTTI实现原理(多态的原理)
- 变速齿轮的原理
- 防火墙的工作原理
- STRICT的原理
- Windows的DDE原理
- 缓冲区溢出的原理
- 缓冲区溢出的原理
- 网页计数器的原理
- java web 的jsp的跳转问题
- volatile用在如下的几个地方
- java开发微信第三方平台 模板消息发送消息案例
- 判断一个正整数是否为2的幂
- 一篇关于Android Root不错的文章
- PageMybatisInterceptor 的原理
- 沉浸式状态栏的实现代码
- ava selenium webdriver实战 helloWord
- Picasso利用Transformation自定义带边框的圆形图片
- easyUI 相关清空功能
- [心得] docker目录迁移心法
- vs2013 mvc 模板 使用的第一个例子
- Tomcat性能调优方案
- JavaScript学习笔记