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);
时间: 2024-10-07 18:47:01

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

SpringMVC分页和搜索分页

分页使我们经常需要使用的功能,昨天在Spring MVC中实现了简单的分页操作和搜索分页,在此记录一下.使用的框架为(MyBatis+SpringMVC+Spring). 首先我们需要一个分页的工具类: 1.分页 import java.io.Serializable; /** * 分页 */ public class Page implements Serializable { private static final long serialVersionUID = -319804844964

SpringMVC之Interceptor拦截器之登录拦截器

SpringMVC的拦截器是主要作用是拦截用户请求到后台之间的请求,在进入后台之前可以对其进行权限认证和用户登录的限制. 1.定义拦截器: springmvc中拦截器中主要有两种方式:第一种是实现HandleInterceptor接口,重写里面的方法:第二种是实现WebRequestInterceptor接口,同样的重写里面的方法,实现自己自定义的逻辑处理. 1.实现handleInterceptor接口: 接口中定义了三个方法:preHandle(requsest,response.handl

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

在用ajax获得分页数据时,无法将获取的值赋值给input标签,在修改用户信息时不显示用户已经注册的信息,百度可知 springmvc处理分页数据返回的对象时,无法直接将对象转换成json,会报org.springframework.http.converter.HttpMessageNotWritableException: No converter found for return value of type:错误, 需要在springmvc返回前先转换为json 步骤如下: 1.添加依赖(

springmvc 异常Interceptor

无论做什么项目,进行异常处理都是非常有必要的,而且你不能把一些只有程序员才能看懂的错误代码抛给用户去看,所以这时候进行统一的异常处理,展现一个比较友好的错误页面就显得很有必要了. springMVC提供的异常处理主要有两种方式,一种是直接实现自己的HandlerExceptionResolver,当然这也包括使用spring已经为我们提供好的SimpleMappingExceptionResolver和DefaultHandlerExceptionResolver,另一种是使用注解的方式实现一个

springmvc 分页查询的简单实现

目前较常用的分页实现办法有两种: 1.每次翻页都修改SQL,向SQL传入相关参数去数据库实时查出该页的数据并显示. 2.查出数据库某张表的全部数据,再通过在业务逻辑里面进行处理去取得某些数据并显示. 对于数据量并不大的简单的管理系统而言,第一种实现方法相对来说容易使用较少的代码实现分页这一功能,本文也正是为大家介绍这种方法: 代码片段: 1,Page.java package com.cm.contract.common; import org.apache.commons.lang.Strin

SpringMVC中Interceptor和Filter区别

Interceptor 主要作用:拦截用户请求,进行处理,比如判断用户登录情况,权限验证,主要针对Action请求进行处理.是通过HandlerInterceptor 实现的. 配置如下: <mvc:interceptors> <bean class="cn.appsys.testInterceptor"></bean>//拦截所有请求 <mvc:interceptor> <mvc:mapping path="/manag

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

本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 当用户点击到网站主页时要进行拦截,用户登录了才能进入网站主页,否则进入登陆页面 核心代码 首先是index.jsp,显示链接 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 2 <% 3 String path = request.getContextPath(); 4 St

SSM框架——实现分页和搜索分页

登录|注册     在路上 在路上,要懂得积累:在路上,要学会放下:我在路上!Stay hungry,Stay foolish. 目录视图 摘要视图 订阅 [公告]博客系统优化升级     [收藏]Html5 精品资源汇集     博乐招募开始啦 SSM框架——实现分页和搜索分页 标签: springMVC分页搜索分页mybatisssm 2014-05-21 11:09 5517人阅读 评论(9) 收藏 举报 分类: J2EE(9) 版权声明:本文为博主原创文章,欢迎转载,请注明地址. 目录(

Spring MVC + Mybatis + Shiro

1.Spring配置:web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/