springMVC分页,interceptor实现
PageInterceptor.java
- @Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class }) })
- public class PageInterceptor implements Interceptor {
- private static final Logger logger = Logger
- .getLogger(PageInterceptor.class);
- private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
- private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
- private static String defaultPageSqlId = ".*Page$"; // 需要拦截的ID(正则匹配)
- private static String pageSqlId = ""; // 需要拦截的ID(正则匹配)
- @Override
- public Object intercept(Invocation invocation) throws Throwable {
- StatementHandler statementHandler = (StatementHandler) invocation
- .getTarget();
- MetaObject metaStatementHandler = MetaObject.forObject(
- statementHandler, DEFAULT_OBJECT_FACTORY,
- DEFAULT_OBJECT_WRAPPER_FACTORY);
- // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环可以分离出最原始的的目标类)
- while (metaStatementHandler.hasGetter("h")) {
- Object object = metaStatementHandler.getValue("h");
- metaStatementHandler = MetaObject.forObject(object,
- DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
- }
- // 分离最后一个代理对象的目标类
- while (metaStatementHandler.hasGetter("target")) {
- Object object = metaStatementHandler.getValue("target");
- metaStatementHandler = MetaObject.forObject(object,
- DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
- }
- Configuration configuration = (Configuration) metaStatementHandler
- .getValue("delegate.configuration");
- Properties properties = configuration.getVariables();
- if (null != properties
- && StringUtils.isNotBlank(properties.getProperty("pageSqlId"))) {
- pageSqlId = properties.getProperty("pageSqlId");
- } else {
- pageSqlId = defaultPageSqlId;
- }
- MappedStatement mappedStatement = (MappedStatement) metaStatementHandler
- .getValue("delegate.mappedStatement");
- // 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的MappedStatement的sql
- if (mappedStatement.getId().matches(pageSqlId)) {
- BoundSql boundSql = (BoundSql) metaStatementHandler
- .getValue("delegate.boundSql");
- Object parameterObject = boundSql.getParameterObject();
- if (parameterObject == null) {
- throw new NullPointerException("parameterObject is null!");
- }
- Map<String, Object> paramMap = (Map) parameterObject;
- PageParameter page = (PageParameter) paramMap.get("0");
- String sql = boundSql.getSql();
- // 重写sql
- String pageSql = buildPageSqlForMysql(sql, page);
- metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
- // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
- metaStatementHandler.setValue("delegate.rowBounds.offset",
- RowBounds.NO_ROW_OFFSET);
- metaStatementHandler.setValue("delegate.rowBounds.limit",
- RowBounds.NO_ROW_LIMIT);
- Connection connection = (Connection) invocation.getArgs()[0];
- // 重设分页参数里的总页数等
- setPageParameter(sql, connection, mappedStatement, boundSql, page);
- }
- // 将执行权交给下一个拦截器
- return invocation.proceed();
- }
- @Override
- public Object plugin(Object target) {
- // 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
- if (target instanceof StatementHandler) {
- return Plugin.wrap(target, this);
- } else {
- return target;
- }
- }
- @Override
- public void setProperties(Properties properties) {
- // TODO Auto-generated method stub
- }
- /**
- * mysql的分页语句
- *
- * @param sql
- * @param page
- * @return String
- */
- public String buildPageSqlForMysql(String sql, PageParameter page) {
- StringBuilder pageSql = new StringBuilder(100);
- String beginrow = String.valueOf((page.getCurrentPage() - 1)
- * page.getPageSize());
- pageSql.append(sql);
- pageSql.append(" limit " + beginrow + "," + page.getPageSize());
- return pageSql.toString();
- }
- private void setPageParameter(String sql, Connection connection,
- MappedStatement mappedStatement, BoundSql boundSql,
- PageParameter page) {
- // 记录总记录数
- String countSql = "select count(0) from (" + sql + ") as total";
- PreparedStatement countStmt = null;
- ResultSet rs = null;
- try {
- countStmt = connection.prepareStatement(countSql);
- BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(),
- countSql, boundSql.getParameterMappings(),
- boundSql.getParameterObject());
- setParameters(countStmt, mappedStatement, countBS,
- boundSql.getParameterObject());
- rs = countStmt.executeQuery();
- int totalCount = 0;
- if (rs.next()) {
- totalCount = rs.getInt(1);
- }
- page.setTotalCount(totalCount);
- int totalPage = totalCount / page.getPageSize()
- + ((totalCount % page.getPageSize() == 0) ? 0 : 1);
- page.setTotalPage(totalPage);
- } catch (SQLException e) {
- logger.error("Ignore this exception", e);
- } finally {
- try {
- rs.close();
- } catch (SQLException e) {
- logger.error("Ignore this exception", e);
- }
- try {
- countStmt.close();
- } catch (SQLException e) {
- logger.error("Ignore this exception", e);
- }
- }
- }
- private void setParameters(PreparedStatement ps,
- MappedStatement mappedStatement, BoundSql boundSql,
- Object parameterObject) throws SQLException {
- ParameterHandler parameterHandler = new DefaultParameterHandler(
- mappedStatement, parameterObject, boundSql);
- parameterHandler.setParameters(ps);
- }
- }
PageParameter.java
- public class PageParameter {
- public static final int DEFAULT_PAGE_SIZE = 10;
- private int pageSize;
- private int currentPage;
- private int prePage;
- private int nextPage;
- private int totalPage;
- private int totalCount;
- public PageParameter() {
- this.currentPage = 1;
- this.pageSize = DEFAULT_PAGE_SIZE;
- }
- /**
- *
- * @param currentPage
- * @param pageSize
- */
- public PageParameter(int currentPage, int pageSize) {
- this.currentPage = currentPage;
- this.pageSize = pageSize;
- }
- public int getCurrentPage() {
- return currentPage;
- }
- public void setCurrentPage(int currentPage) {
- this.currentPage = currentPage;
- }
- public int getPageSize() {
- return pageSize;
- }
- public void setPageSize(int pageSize) {
- this.pageSize = pageSize;
- }
- public int getPrePage() {
- return prePage;
- }
- public void setPrePage(int prePage) {
- this.prePage = prePage;
- }
- public int getNextPage() {
- return nextPage;
- }
- public void setNextPage(int nextPage) {
- this.nextPage = nextPage;
- }
- public int getTotalPage() {
- return totalPage;
- }
- public void setTotalPage(int totalPage) {
- this.totalPage = totalPage;
- }
- public int getTotalCount() {
- return totalCount;
- }
- public void setTotalCount(int totalCount) {
- this.totalCount = totalCount;
- }
- public String toString() {
- return ToStringBuilder.reflectionToString(this);
- }
- }
mybatis-config.xml配置
- <?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>
- <plugins>
- <plugin interceptor="*.*.PageInterceptor"></plugin>
- </plugins>
- </configuration>
使用:
- Map<String, Object> paramMap = new HashMap<String, Object>();
- PageParameter pageParameter = new PageParameter();
- pageParameter.setCurrentPage(10000);
- userService.findUserPage(pageParameter, null);
springMVC分页,interceptor实现的更多相关文章
- springmvc之interceptor(拦截器)
1.自定义MyInterceptor impletments HandlerInterceptor public class MyInterceptor implements HandlerInter ...
- SpringMvc中Interceptor拦截器用法
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆等. 一. 使用场景 1 ...
- springMVC之Interceptor拦截器
转自:https://blog.csdn.net/qq_25673113/article/details/79153547 Interceptor拦截器用于拦截Controller层接口,表现形式有点 ...
- SpringMVC分页查询无法直接将对象转换成json的解决办法(报org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type:错)
在用ajax获得分页数据时,无法将获取的值赋值给input标签,在修改用户信息时不显示用户已经注册的信息,百度可知 springmvc处理分页数据返回的对象时,无法直接将对象转换成json,会报org ...
- springmvc 异常Interceptor
无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了. springMVC提 ...
- SpringMVC中Interceptor和Filter区别
Interceptor 主要作用:拦截用户请求,进行处理,比如判断用户登录情况,权限验证,主要针对Action请求进行处理.是通过HandlerInterceptor 实现的. 配置如下: <m ...
- springmvc学习笔记--Interceptor机制和实践
前言: Spring的AOP理念, 以及j2ee中责任链(过滤器链)的设计模式, 确实深入人心, 处处可以看到它的身影. 这次借项目空闲, 来总结一下SpringMVC的Interceptor机制, ...
- SpringMVC学习记录5
Springmvc流程中的扩展点有很多,可以在很多地方插入自己的代码逻辑达到控制流程的目的. 如果要对Controller的handler方法做统一的处理.我想应该会有很多选择,比如:@ModelAt ...
- SpringMVC拦截器(实现登录验证拦截器)
本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 当用户点击到网站主页时要进行拦截,用户登录了才能进入网站主页,否则进入登陆页面 核心代码 首先是index.jsp,显示链接 <%@ ...
随机推荐
- EF架构~在Linq to Entity中使用日期函數
回到目录 眾所周知,在linq to entity的查询语句中,不允许出现ef不能识别的关键字,如Trim,Substring,TotalDays等.net里的关键字,在EF查询里都是不被支持的,它的 ...
- IDE:Eclipse查看接口实现类快捷键
1.打开接口类 2.双击接口名选中 3.Ctrl+T,打开接口实现类
- ASPNET MVC中断请求
ASPNET MVC如何正确的中断请求? 感觉是这样? 在aspnet开发过程中如果想要中断当前的http处理,以前在aspnet中一直是Response.End(); 在这Response.End( ...
- 解析大型.NET ERP系统 企业信息化实施人员工具箱
1 第一次实施会议 当签订合同之后,软件公司与客户约定好会议时间,双方召开第一次实施会议,确定实施的小组人员名单,项目实施周期,培训计划表,实施主计划,系统预备主文件数据准备,软件公司技术支持联系方式 ...
- WPF/Silverlight 下的图片局部放大
最近的项目中也要用到一个局部图片放大的功能,园子里面一搜,发现(菩提下的杨过)杨大侠已经实现了. 请参见这里:http://www.cnblogs.com/yjmyzz/archive/2009/12 ...
- 动画animation的三个应用(漂浮的白云、旋转的星球、正方体合成)
× 目录 [1]漂浮的白云 [2]旋转的星球 [3]正方体合成 前面的话 前面介绍过动画animation的详细用法,本文主要介绍动画animation的三个效果 漂浮的白云 [效果演示] [简要介绍 ...
- mysql 命令重命名表RENAME TABLE 句法
mysql 命令重命名表RENAME TABLE 句法 RENAME TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2,...]更 ...
- isDebugEnabled有什么用?
这几天在读Spring MVC源码时,发现了如下代码: if (logger.isDebugEnabled()) { logger.debug("Using ThemeResolver [& ...
- Javascript模块化开发,使用模块化脚本加载工具RequireJS,提高你代码的速度和质量。
随着前端JavaScript代码越来越重,如何组织JavaScript代码变得非常重要,好的组织方式,可以让别人和自己很好的理解代码,也便于维护和测试.模块化是一种非常好的代码组织方式,本文试着对Ja ...
- Vim魔法堂:认识快捷键绑定
Brief 习惯在VS上按<F5>来编译运行程序,刚用上VIM上就觉得无比的麻烦,而随着对VIM的学习我们分阶段的简化这一操作 1. 退出VIM,在shell下编译&&运行 ...