(一)关于分页拦截器的简单理解

首先,要开发MyBatis的插件需要实现org.apache.ibatis.plugin.Interceptor接口,这个接口将会要求实现几个方法:intercept()、plugin()及setProperties(),intercept方法是开发人员所要执行的操作,plugin是将你插件放入到MyBatis的插件集合中去,而setProperties这是在你配置你插件的时候将plugins/plugin/properties的值设置到该插件中。
    该方法的第一句话就是获得Intercepts注解,接下来将获得在Intercepts里面的参数@Signature注解内容,在该注解中包含三个参数,分别是type,method,args。Type指定要拦截的类对象,method是指明要拦截该类的哪个方法,第三个是指明要拦截的方法参数集合。在Intercepts中可以配置多个@Signature。那么便对这写值进行遍历,已获得对应的type、method以及args。最终是获得一个HashMap对象,这些对象里面的键是类对象,而值是指定的类中方法对象。执行该端程序之后,更具target的classLoader和接口,来创建一个代理,并且,InvocationHandler是创建一个新的Plugin对象,同时将target,interceptor以及signatureMap传递给Plugin对象,当然,这里的Plugin也实现了Invocation接口。那么target对象所有的方法调用都会触发Plugin中的invoke方法,那么这里将执行开发者所有插入的操作。

另外对拦截器类里面几个关键的类做出解释:

(1)BoundSql类 ,封装mybatis最终产生sql的类,包括sql语句,参数,参数源数据等。
(2)MappedStatement类,MappedStatement类在Mybatis框架中用于表示XML文件中一个sql语句节点,即一个<select />、<update />或者<insert />标签。Mybatis框架在初始化阶段会对XML配置文件进行读取,将其中的sql语句节点对象化为一个个MappedStatement对象。

总结,本拦截器实现的目标就是在进行数据库查询操作之前,从配置文件读出相应的sql语句,将相应的参数拼接到其中,然后再进行查询。当然在拼接sql语句之前,先查询了一下数据库中相应记录的总数

(二)拦截器类PageIntercepter.java:

  1. package cn.zyy.paging.intercepter;
  2. import java.sql.Connection;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.util.List;
  7. import java.util.Properties;
  8. import org.apache.ibatis.mapping.BoundSql;
  9. import org.apache.ibatis.mapping.MappedStatement;
  10. import org.apache.ibatis.mapping.ParameterMapping;
  11. import org.apache.ibatis.mapping.ParameterMode;
  12. import org.apache.ibatis.mapping.SqlSource;
  13. import org.apache.ibatis.plugin.Interceptor;
  14. import org.apache.ibatis.plugin.Intercepts;
  15. import org.apache.ibatis.plugin.Invocation;
  16. import org.apache.ibatis.plugin.Plugin;
  17. import org.apache.ibatis.reflection.MetaObject;
  18. import org.apache.ibatis.session.Configuration;
  19. import org.apache.ibatis.session.RowBounds;
  20. import org.apache.ibatis.type.TypeHandler;
  21. import org.apache.ibatis.type.TypeHandlerRegistry;
  22. import cn.zyy.paging.vo.PageObject;
  23. @Intercepts({@org.apache.ibatis.plugin.Signature(method="query", type=org.apache.ibatis.executor.Executor.class, args={MappedStatement.class, Object.class, RowBounds.class, org.apache.ibatis.session.ResultHandler.class})})
  24. public class PageIntercepter implements Interceptor{
  25. @Override
  26. public Object intercept(Invocation invocation) throws Throwable {
  27. MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
  28. Object object = invocation.getArgs()[1];
  29. if(object instanceof PageObject){
  30. PageObject pageObject = (PageObject) object;
  31. BoundSql boundSql = mappedStatement.getBoundSql(object);
  32. String sql = boundSql.getSql();
  33. int count = getCount(mappedStatement,boundSql);
  34. pageObject.setCount(count);
  35. int pages = (pageObject.getCount()+pageObject.getNumber()-1)/pageObject.getNumber();
  36. pageObject.setPages(pages>0?pages:1);
  37. int offset = (pageObject.getPage() - 1) * pageObject.getNumber();
  38. int limit = pageObject.getNumber();
  39. String pageSql = pageSql(sql, offset, limit);
  40. BoundSql pageBoundSql = new BoundSql(mappedStatement.getConfiguration(), pageSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
  41. MappedStatement pageMappedStatement = pageMappedStatement(mappedStatement, new PageSqlSource(pageBoundSql));
  42. invocation.getArgs()[0] = pageMappedStatement;
  43. invocation.getArgs()[2] = RowBounds.DEFAULT;
  44. }
  45. return invocation.proceed();
  46. }
  47. @Override
  48. public Object plugin(Object object) {
  49. // TODO Auto-generated method stub
  50. return Plugin.wrap(object, this);
  51. }
  52. @Override
  53. public void setProperties(Properties properties) {
  54. // TODO Auto-generated method stub
  55. }
  56. private int getCount(MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {
  57. Connection connection = null;
  58. PreparedStatement ps = null;
  59. ResultSet rs = null;
  60. try {
  61. String countSql = countSql(boundSql.getSql());
  62. connection = mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection();
  63. ps = connection.prepareStatement(countSql);
  64. BoundSql countBoundSql = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), boundSql.getParameterObject());
  65. setCountParameters(ps, mappedStatement, countBoundSql);
  66. rs = ps.executeQuery();
  67. int count = 0;
  68. if (rs.next())
  69. {
  70. count = rs.getInt(1);
  71. }
  72. return count;
  73. } catch (Exception e) {
  74. return 1000;
  75. }finally{
  76. try {
  77. rs.close();
  78. } catch (Exception localException4) {
  79. }
  80. try {
  81. ps.close();
  82. } catch (Exception localException5) {
  83. }
  84. try {
  85. connection.close();
  86. }
  87. catch (Exception localException6) {
  88. }
  89. }
  90. }
  91. private static String countSql(String sql){
  92. sql = sql.toUpperCase();
  93. StringBuffer countSql = new StringBuffer();
  94. countSql.append("SELECT COUNT(1) FROM (");
  95. countSql.append(sql.substring(0, sql.indexOf("ORDER BY")==-1?sql.length():sql.indexOf("ORDER BY")-1));
  96. countSql.append(") PAY_PAGE_T");
  97. return countSql.toString();
  98. }
  99. private static void setCountParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql) throws SQLException {
  100. List<ParameterMapping> parameterMappingList = boundSql.getParameterMappings();
  101. if (parameterMappingList != null)
  102. {
  103. Configuration configuration = mappedStatement.getConfiguration();
  104. TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
  105. Object parameterObject = boundSql.getParameterObject();
  106. MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
  107. int n = 1;
  108. for (ParameterMapping parameterMapping : parameterMappingList)
  109. {
  110. if ((parameterMapping.getMode() == ParameterMode.IN) || (parameterMapping.getMode() == ParameterMode.INOUT))
  111. {
  112. String property = parameterMapping.getProperty();
  113. Object value = null;
  114. if (parameterObject != null)
  115. {
  116. if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))
  117. {
  118. value = parameterObject;
  119. }
  120. else
  121. {
  122. value = metaObject == null ? null : metaObject.getValue(property);
  123. }
  124. }
  125. TypeHandler typeHandler = parameterMapping.getTypeHandler();
  126. typeHandler.setParameter(ps, n, value, parameterMapping.getJdbcType());
  127. }
  128. n++;
  129. }
  130. }
  131. }
  132. private String pageSql(String sql, int offset, int limit) {
  133. sql = sql.toUpperCase();
  134. StringBuffer pageSql = new StringBuffer();
  135. pageSql.append(sql);
  136. pageSql.append(" LIMIT ");
  137. pageSql.append(offset);
  138. pageSql.append(", ");
  139. pageSql.append(limit);
  140. return pageSql.toString();
  141. }
  142. private MappedStatement pageMappedStatement(MappedStatement mappedStatement, SqlSource sqlSource)
  143. {
  144. MappedStatement.Builder builder = new MappedStatement.Builder(
  145. mappedStatement.getConfiguration(),
  146. mappedStatement.getId(),
  147. sqlSource,
  148. mappedStatement.getSqlCommandType());
  149. builder.resource(mappedStatement.getResource());
  150. builder.fetchSize(mappedStatement.getFetchSize());
  151. builder.statementType(mappedStatement.getStatementType());
  152. builder.keyGenerator(mappedStatement.getKeyGenerator());
  153. builder.timeout(mappedStatement.getTimeout());
  154. builder.parameterMap(mappedStatement.getParameterMap());
  155. builder.resultMaps(mappedStatement.getResultMaps());
  156. builder.cache(mappedStatement.getCache());
  157. builder.resultSetType(mappedStatement.getResultSetType());
  158. builder.flushCacheRequired(mappedStatement.isFlushCacheRequired());
  159. builder.useCache(mappedStatement.isUseCache());
  160. builder.resultOrdered(mappedStatement.isResultOrdered());
  161. builder.databaseId(mappedStatement.getDatabaseId());
  162. builder.lang(mappedStatement.getLang());
  163. if (mappedStatement.getKeyProperties() != null)
  164. {
  165. for (String keyProperty : mappedStatement.getKeyProperties())
  166. {
  167. builder.keyProperty(keyProperty);
  168. }
  169. }
  170. if (mappedStatement.getKeyColumns() != null)
  171. {
  172. for (String keyColumn : mappedStatement.getKeyColumns())
  173. {
  174. builder.keyColumn(keyColumn);
  175. }
  176. }
  177. return builder.build();
  178. }
  179. public static class PageSqlSource implements SqlSource {
  180. private BoundSql boundSql;
  181. public PageSqlSource(BoundSql boundSql) {
  182. this.boundSql = boundSql;
  183. }
  184. public BoundSql getBoundSql(Object parameterObject)
  185. {
  186. return this.boundSql;
  187. }
  188. }
  189. }

(三)spring配置文件和mybatis配置文件

mybatis配置文件中主要是配置相关的vo类和拦截器

[html] view plain copy

mybatis框架下物理分页的实现(整个工程采用的是springmvc、spring、mybatis框架,数据库是mysql数据库)的更多相关文章

  1. ssm项目框架搭建(增删改查案例实现)——(SpringMVC+Spring+mybatis项目整合)

    Spring 常用注解 内容 一.基本概念 1. Spring 2. SpringMVC 3. MyBatis 二.开发环境搭建 1. 创建 maven 项目 2. SSM整合 2.1 项目结构图 2 ...

  2. 手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版)

    手把手Maven搭建SpringMVC+Spring+MyBatis框架(超级详细版) SSM(Spring+SpringMVC+Mybatis),目前较为主流的企业级架构方案.标准的MVC设计模式, ...

  3. spring+websocket综合(springMVC+spring+MyBatis这是SSM框架和websocket集成技术)

    java-websocket该建筑是easy.儿童无用的框架可以在这里下载主线和个人教学好java-websocket计划: Apach Tomcat 8.0.3+MyEclipse+maven+JD ...

  4. springMVC,spring,mybatis全注解搭建框架--第一步,让框架跑起来

    自己从事java开发工作也有一年多了,自己却没有亲手搭建一个完整的框架.于是今天自己动手搭建一个,过程中遇到一些问题,倒腾了大半天终于搞定了. 现在给大家分享一下过程,自己也记录下来,以后学习参考使用 ...

  5. 单工程搭建springmvc+spring+mybatis(maven,idea)

    单工程搭建springmvc+spring+mybatis(maven,idea) 1.pom.xml <properties> <project.build.sourceEncod ...

  6. (一)springmvc+spring+mybatis+maven框架搭建

    (一)springmvc+spring+mybatis+maven框架搭建 1.说明 工作之余,为了学习点东西.先搭建个框架. 以后要往里面加东西,比如rabbitMQ.redis.shiro等. 也 ...

  7. SSM(SpringMVC+Spring+MyBatis)三大框架使用Maven快速搭建整合(实现数据库数据到页面进行展示)

    本文介绍使用SpringMVC+Spring+MyBatis三大框架使用Maven快速搭建一个demo,实现数据从数据库中查询返回到页面进行展示的过程. 技术选型:SpringMVC+Spring+M ...

  8. SpringMVC+Spring+mybatis+maven+搭建多模块框架前后端分离开发框架的完整demo,拿走不谢。——猿实战02

            猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...

  9. 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01

            猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...

  10. SSM(SpringMVC+Spring+Mybatis)框架学习理解

    近期做到的项目中,用到的框架是SSM(SpringMVC+Spring+Mybatis).之前比较常见的是SSH.用到了自然得了解各部分的分工 spring mvc 是spring 处理web层请求的 ...

随机推荐

  1. E - Tears of Drowned

    Description Tia Dalma: Come. What service may I do you? You know I demand payment. Jack: I brought p ...

  2. Oracle开发包被锁解决办法-终极办法

    http://www.itpub.net/forum.php?mod=viewthread&tid=1761963 以前在数据库维护中,基本都是碰到表被锁的情况,然后就是查找被锁的表相关的信息 ...

  3. Android-Kotlin-抽象类与多态的表现

    选择包名,然后右键: 选择Class类型,会有class:  选择File类型,不会自动有class: 目录结构: 定义描述抽象类 Person人类: package cn.kotlin.kotlin ...

  4. wpf 导出Excel

    private void Button_Click_1(object sender, RoutedEventArgs e) { ExportDataGridSaveAs(true, this.data ...

  5. Python 库,资源

    库名称简介 Chardet字符编码探测器,可以自动检测文本.网页.xml的编码. colorama主要用来给文本添加各种颜色,并且非常简单易用. Prettytable主要用于在终端或浏览器端构建格式 ...

  6. 同一域名基于源ip地址分配给不同ip的dns配置--bind9.8.2

    1.安装bind.略. 2./etc/named.conf配置文件. // named.conf // // Provided by Red Hat bind package to configure ...

  7. .NET Core 常用加密和Hash工具NETCore.Encrypt

    前言 在日常开发过程中,不可避免的涉及到数据加密解密(Hash)操作,所以就有想法开发通用工具,NETCore.Encrypt就诞生了.目前NETCore.Encrypt只支持.NET Core ,工 ...

  8. yarn 学习 小记

    官网:https://yarnpkg.com/zh-Hans/docs/installing-dependencies 简介:包管理工具,和npm类似主要特点:快速.安全.可靠 快速:本地安装包后,会 ...

  9. SQL高效查询两个表不同的数据

    逻辑相对复杂,但是速度最快: )

  10. 微信小程序报Cannot read property 'setData' of undefined的错误

    最近在学习微信小程序的开发,让我吐槽的是,都9102年了,怎么还是有有时不能复制,有时不能打中文的bug呢,这个时候,你可以Ctrl+shift+w一下,如果还不行,那就得重启了.. 进入正题吧,刚在 ...