PageInterceptor.java

  1. @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
  2. public class PageInterceptor implements Interceptor {
  3. private static final Logger logger = Logger
  4. .getLogger(PageInterceptor.class);
  5. private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
  6. private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
  7. private static String defaultPageSqlId = ".*Page$"; // 需要拦截的ID(正则匹配)
  8. private static String pageSqlId = ""; // 需要拦截的ID(正则匹配)
  9.  
  10. @Override
  11. public Object intercept(Invocation invocation) throws Throwable {
  12. StatementHandler statementHandler = (StatementHandler) invocation
  13. .getTarget();
  14. MetaObject metaStatementHandler = MetaObject.forObject(
  15. statementHandler, DEFAULT_OBJECT_FACTORY,
  16. DEFAULT_OBJECT_WRAPPER_FACTORY);
  17. // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环可以分离出最原始的的目标类)
  18. while (metaStatementHandler.hasGetter("h")) {
  19. Object object = metaStatementHandler.getValue("h");
  20. metaStatementHandler = MetaObject.forObject(object,
  21. DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
  22. }
  23. // 分离最后一个代理对象的目标类
  24. while (metaStatementHandler.hasGetter("target")) {
  25. Object object = metaStatementHandler.getValue("target");
  26. metaStatementHandler = MetaObject.forObject(object,
  27. DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
  28. }
  29. Configuration configuration = (Configuration) metaStatementHandler
  30. .getValue("delegate.configuration");
  31. Properties properties = configuration.getVariables();
  32. if (null != properties
  33. && StringUtils.isNotBlank(properties.getProperty("pageSqlId"))) {
  34. pageSqlId = properties.getProperty("pageSqlId");
  35. } else {
  36. pageSqlId = defaultPageSqlId;
  37. }
  38.  
  39. MappedStatement mappedStatement = (MappedStatement) metaStatementHandler
  40. .getValue("delegate.mappedStatement");
  41. // 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的MappedStatement的sql
  42. if (mappedStatement.getId().matches(pageSqlId)) {
  43. BoundSql boundSql = (BoundSql) metaStatementHandler
  44. .getValue("delegate.boundSql");
  45. Object parameterObject = boundSql.getParameterObject();
  46.  
  47. if (parameterObject == null) {
  48. throw new NullPointerException("parameterObject is null!");
  49. }
  50. Map<String, Object> paramMap = (Map) parameterObject;
  51.  
  52. PageParameter page = (PageParameter) paramMap.get("0");
  53. String sql = boundSql.getSql();
  54. // 重写sql
  55. String pageSql = buildPageSqlForMysql(sql, page);
  56. metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
  57. // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
  58. metaStatementHandler.setValue("delegate.rowBounds.offset",
  59. RowBounds.NO_ROW_OFFSET);
  60. metaStatementHandler.setValue("delegate.rowBounds.limit",
  61. RowBounds.NO_ROW_LIMIT);
  62. Connection connection = (Connection) invocation.getArgs()[0];
  63. // 重设分页参数里的总页数等
  64. setPageParameter(sql, connection, mappedStatement, boundSql, page);
  65. }
  66. // 将执行权交给下一个拦截器
  67. return invocation.proceed();
  68. }
  69.  
  70. @Override
  71. public Object plugin(Object target) {
  72. // 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
  73. if (target instanceof StatementHandler) {
  74. return Plugin.wrap(target, this);
  75. } else {
  76. return target;
  77. }
  78. }
  79.  
  80. @Override
  81. public void setProperties(Properties properties) {
  82. // TODO Auto-generated method stub
  83.  
  84. }
  85.  
  86. /**
  87. * mysql的分页语句
  88. *
  89. * @param sql
  90. * @param page
  91. * @return String
  92. */
  93. public String buildPageSqlForMysql(String sql, PageParameter page) {
  94. StringBuilder pageSql = new StringBuilder(100);
  95. String beginrow = String.valueOf((page.getCurrentPage() - 1)
  96. * page.getPageSize());
  97. pageSql.append(sql);
  98. pageSql.append(" limit " + beginrow + "," + page.getPageSize());
  99. return pageSql.toString();
  100. }
  101.  
  102. private void setPageParameter(String sql, Connection connection,
  103. MappedStatement mappedStatement, BoundSql boundSql,
  104. PageParameter page) {
  105. // 记录总记录数
  106. String countSql = "select count(0) from (" + sql + ") as total";
  107. PreparedStatement countStmt = null;
  108. ResultSet rs = null;
  109. try {
  110. countStmt = connection.prepareStatement(countSql);
  111. BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(),
  112. countSql, boundSql.getParameterMappings(),
  113. boundSql.getParameterObject());
  114. setParameters(countStmt, mappedStatement, countBS,
  115. boundSql.getParameterObject());
  116. rs = countStmt.executeQuery();
  117. int totalCount = 0;
  118. if (rs.next()) {
  119. totalCount = rs.getInt(1);
  120. }
  121. page.setTotalCount(totalCount);
  122. int totalPage = totalCount / page.getPageSize()
  123. + ((totalCount % page.getPageSize() == 0) ? 0 : 1);
  124. page.setTotalPage(totalPage);
  125.  
  126. } catch (SQLException e) {
  127. logger.error("Ignore this exception", e);
  128. } finally {
  129. try {
  130. rs.close();
  131. } catch (SQLException e) {
  132. logger.error("Ignore this exception", e);
  133. }
  134. try {
  135. countStmt.close();
  136. } catch (SQLException e) {
  137. logger.error("Ignore this exception", e);
  138. }
  139. }
  140.  
  141. }
  142.  
  143. private void setParameters(PreparedStatement ps,
  144. MappedStatement mappedStatement, BoundSql boundSql,
  145. Object parameterObject) throws SQLException {
  146. ParameterHandler parameterHandler = new DefaultParameterHandler(
  147. mappedStatement, parameterObject, boundSql);
  148. parameterHandler.setParameters(ps);
  149. }
  150. }

PageParameter.java

  1. public class PageParameter {
  2. public static final int DEFAULT_PAGE_SIZE = 10;
  3.  
  4. private int pageSize;
  5. private int currentPage;
  6. private int prePage;
  7. private int nextPage;
  8. private int totalPage;
  9. private int totalCount;
  10.  
  11. public PageParameter() {
  12. this.currentPage = 1;
  13. this.pageSize = DEFAULT_PAGE_SIZE;
  14. }
  15.  
  16. /**
  17. *
  18. * @param currentPage
  19. * @param pageSize
  20. */
  21. public PageParameter(int currentPage, int pageSize) {
  22. this.currentPage = currentPage;
  23. this.pageSize = pageSize;
  24. }
  25.  
  26. public int getCurrentPage() {
  27. return currentPage;
  28. }
  29.  
  30. public void setCurrentPage(int currentPage) {
  31. this.currentPage = currentPage;
  32. }
  33.  
  34. public int getPageSize() {
  35. return pageSize;
  36. }
  37.  
  38. public void setPageSize(int pageSize) {
  39. this.pageSize = pageSize;
  40. }
  41.  
  42. public int getPrePage() {
  43. return prePage;
  44. }
  45.  
  46. public void setPrePage(int prePage) {
  47. this.prePage = prePage;
  48. }
  49.  
  50. public int getNextPage() {
  51. return nextPage;
  52. }
  53.  
  54. public void setNextPage(int nextPage) {
  55. this.nextPage = nextPage;
  56. }
  57.  
  58. public int getTotalPage() {
  59. return totalPage;
  60. }
  61.  
  62. public void setTotalPage(int totalPage) {
  63. this.totalPage = totalPage;
  64. }
  65.  
  66. public int getTotalCount() {
  67. return totalCount;
  68. }
  69.  
  70. public void setTotalCount(int totalCount) {
  71. this.totalCount = totalCount;
  72. }
  73.  
  74. public String toString() {
  75. return ToStringBuilder.reflectionToString(this);
  76. }
  77. }

mybatis-config.xml配置

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <plugins>
  7. <plugin interceptor="*.*.PageInterceptor"></plugin>
  8. </plugins>
  9. </configuration>

使用:

  1. Map<String, Object> paramMap = new HashMap<String, Object>();
  2. PageParameter pageParameter = new PageParameter();
  3. pageParameter.setCurrentPage(10000);
  4. userService.findUserPage(pageParameter, null);

springMVC分页,interceptor实现的更多相关文章

  1. springmvc之interceptor(拦截器)

    1.自定义MyInterceptor impletments HandlerInterceptor public class MyInterceptor implements HandlerInter ...

  2. SpringMvc中Interceptor拦截器用法

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆等. 一. 使用场景 1 ...

  3. springMVC之Interceptor拦截器

    转自:https://blog.csdn.net/qq_25673113/article/details/79153547 Interceptor拦截器用于拦截Controller层接口,表现形式有点 ...

  4. SpringMVC分页查询无法直接将对象转换成json的解决办法(报org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type:错)

    在用ajax获得分页数据时,无法将获取的值赋值给input标签,在修改用户信息时不显示用户已经注册的信息,百度可知 springmvc处理分页数据返回的对象时,无法直接将对象转换成json,会报org ...

  5. springmvc 异常Interceptor

    无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了. springMVC提 ...

  6. SpringMVC中Interceptor和Filter区别

    Interceptor 主要作用:拦截用户请求,进行处理,比如判断用户登录情况,权限验证,主要针对Action请求进行处理.是通过HandlerInterceptor 实现的. 配置如下: <m ...

  7. springmvc学习笔记--Interceptor机制和实践

    前言: Spring的AOP理念, 以及j2ee中责任链(过滤器链)的设计模式, 确实深入人心, 处处可以看到它的身影. 这次借项目空闲, 来总结一下SpringMVC的Interceptor机制, ...

  8. SpringMVC学习记录5

    Springmvc流程中的扩展点有很多,可以在很多地方插入自己的代码逻辑达到控制流程的目的. 如果要对Controller的handler方法做统一的处理.我想应该会有很多选择,比如:@ModelAt ...

  9. SpringMVC拦截器(实现登录验证拦截器)

    本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 当用户点击到网站主页时要进行拦截,用户登录了才能进入网站主页,否则进入登陆页面 核心代码 首先是index.jsp,显示链接 <%@ ...

随机推荐

  1. EF架构~在Linq to Entity中使用日期函數

    回到目录 眾所周知,在linq to entity的查询语句中,不允许出现ef不能识别的关键字,如Trim,Substring,TotalDays等.net里的关键字,在EF查询里都是不被支持的,它的 ...

  2. IDE:Eclipse查看接口实现类快捷键

    1.打开接口类 2.双击接口名选中 3.Ctrl+T,打开接口实现类

  3. ASPNET MVC中断请求

    ASPNET MVC如何正确的中断请求? 感觉是这样? 在aspnet开发过程中如果想要中断当前的http处理,以前在aspnet中一直是Response.End(); 在这Response.End( ...

  4. 解析大型.NET ERP系统 企业信息化实施人员工具箱

    1 第一次实施会议 当签订合同之后,软件公司与客户约定好会议时间,双方召开第一次实施会议,确定实施的小组人员名单,项目实施周期,培训计划表,实施主计划,系统预备主文件数据准备,软件公司技术支持联系方式 ...

  5. WPF/Silverlight 下的图片局部放大

    最近的项目中也要用到一个局部图片放大的功能,园子里面一搜,发现(菩提下的杨过)杨大侠已经实现了. 请参见这里:http://www.cnblogs.com/yjmyzz/archive/2009/12 ...

  6. 动画animation的三个应用(漂浮的白云、旋转的星球、正方体合成)

    × 目录 [1]漂浮的白云 [2]旋转的星球 [3]正方体合成 前面的话 前面介绍过动画animation的详细用法,本文主要介绍动画animation的三个效果 漂浮的白云 [效果演示] [简要介绍 ...

  7. mysql 命令重命名表RENAME TABLE 句法

    mysql 命令重命名表RENAME TABLE 句法 RENAME TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2,...]更 ...

  8. isDebugEnabled有什么用?

    这几天在读Spring MVC源码时,发现了如下代码: if (logger.isDebugEnabled()) { logger.debug("Using ThemeResolver [& ...

  9. Javascript模块化开发,使用模块化脚本加载工具RequireJS,提高你代码的速度和质量。

    随着前端JavaScript代码越来越重,如何组织JavaScript代码变得非常重要,好的组织方式,可以让别人和自己很好的理解代码,也便于维护和测试.模块化是一种非常好的代码组织方式,本文试着对Ja ...

  10. Vim魔法堂:认识快捷键绑定

    Brief 习惯在VS上按<F5>来编译运行程序,刚用上VIM上就觉得无比的麻烦,而随着对VIM的学习我们分阶段的简化这一操作 1. 退出VIM,在shell下编译&&运行 ...