JSP标签实现分页功能(ORM-mybatis)

来源:互联网 发布:金天鹅软件 编辑:程序博客网 时间:2024/05/29 03:51

分页对象

package com.pcitc.modules.pagination;import java.io.Serializable;import java.util.Arrays;import java.util.List;/** * 通用分页类 * @author mi * * @param <T> */public class Pagination<T> implements Serializable{    private static final long serialVersionUID = 1L;    public static final int DEF_PAGE_SIZE = 3; //默认显示10条数据    public static final int DEF_DISLAY_PAGENUM = 10; //默认显示十个页码    protected int displayPageNum = DEF_DISLAY_PAGENUM; //默认显示10个页码    protected int totalCount = 0; //总记录条数    protected int pageSize = DEF_PAGE_SIZE; //页面中显示的数据多少    protected int pageNo = 1; //当前页码    protected List<T> pageData; //分页中显示的数据的集合    protected int startRow = 0;//起始行    protected int totalPageNo; //总的页码数    protected int[] pageNums; //页面显示的页码集    private String pageSizeName;    private String pageNoName;    private String totalCountName;    public Pagination() {    }    /**     * 构造器     *      * @param pageNo     *            页码     * @param pageSize     *            每页几条数据     * @param totalCount     *            总共几条数据     */    public Pagination(int pageNo, int pageSize, int totalCount) {        setPageSize(pageSize);        setTotalCount(totalCount);        setPageNo(pageNo);        calculateTotalPageNo(); //计算总的页码数        adjustPageNo(); //调整页码        caculateStartRow(); //进行startRow的计算        calculateDisNum(); //进行页码显示计算    }    /**     * 进行总的参数的调整,适合setter所有参数后,进行参数的调整     */    public void adjustAllProcess(){        calculateTotalPageNo(); //计算总的页码数        adjustPageNo(); //调整页码        caculateStartRow(); //进行startRow的计算        calculateDisNum(); //进行页码显示计算    }    /**     * 调整传入的请求页码     */    public void adjustPageNo() {        if(this.totalPageNo < this.pageNo && this.totalPageNo > 0){            this.pageNo = this.totalPageNo;        }    }    /**     * 进行startRow的计算     */    public void caculateStartRow() {        this.startRow = (this.pageNo -1) * this.pageSize;    }    /**     * 计算总的页码数,注意这样一定要先注入pageSize和totalCount     */    public void calculateTotalPageNo() {        this.totalPageNo = this.totalCount%this.pageSize == 0?this.totalCount/this.pageSize:this.totalCount/this.pageSize+1;    }    /**     * 获得页码     */    public int getPageNo() {        return pageNo;    }    /**     * 每页几条数据     */    public int getPageSize() {        return pageSize;    }    /**     * 总共几条数据     */    public int getTotalCount() {        return totalCount;    }    /**     * 是否第一页     */    public boolean isFirstPage() {        return pageNo <= 1;    }    /**     * 是否最后一页     */    public boolean isLastPage() {        return pageNo >= this.totalPageNo;    }    /**     * 下一页页码     */    public int getNextPage() {        if (isLastPage()) {            return pageNo;        } else {            return pageNo + 1;        }    }    /**     * 上一页页码     */    public int getPrePage() {        if (isFirstPage()) {            return pageNo;        } else {            return pageNo - 1;        }    }    /**     * if totalCount<0 then totalCount=0     *      * @param totalCount     */    public void setTotalCount(int totalCount) {        if (totalCount < 0) {            this.totalCount = 0;        } else {            this.totalCount = totalCount;        }    }    /**     * if pageSize< 1 then pageSize=DEF_COUNT     *      * @param pageSize     */    public void setPageSize(int pageSize) {        if (pageSize < 1) {            this.pageSize = DEF_PAGE_SIZE;        } else {            this.pageSize = pageSize;        }    }    /**     * if pageNo < 1 then pageNo=1     *      * @param pageNo     */    public void setPageNo(int pageNo) {        if (pageNo < 1) {            this.pageNo = 1;        } else {            this.pageNo = pageNo;        }    }    /**     * 进行显示页码的计算     */    public void calculateDisNum(){        if(this.totalPageNo > this.displayPageNum){            this.pageNums = new int[this.displayPageNum];            int bet = (this.displayPageNum % 2 == 0 ? this.displayPageNum /2 : (this.displayPageNum /2+1));            if(this.pageNo <= bet){                for(int i=1;i<=this.displayPageNum;i++){                    pageNums[i-1] = i;                }            }else{                //后面没有那么多                if((this.pageNo + bet) > this.totalPageNo){                    for(int i=(this.totalPageNo-this.displayPageNum+1),j=0;i<=this.totalPageNo;i++,j++){                        this.pageNums[j] = i;                    }                }else{                    //偶数                    if(this.displayPageNum % 2 == 0){                        for(int i=(this.pageNo-bet),j=0;i<=(this.pageNo+bet-1);i++){                            this.pageNums[j] = i;                            j++;                        }                    }else{                        for(int i=(this.pageNo-bet+1),j=0;i<=(this.pageNo+bet-1);i++){                            System.out.println(i);                            this.pageNums[j] = i;                            j++;                        }                    }                }            }        }else{            this.pageNums = new int[this.totalPageNo];            for(int i=1;i<=this.totalPageNo;i++){                this.pageNums[i-1] = i;            }        }    }    public List<T> getPageData() {        return pageData;    }    public void setPageData(List<T> pageData) {        this.pageData = pageData;    }    public int getStartRow() {        return startRow;    }    public void setStartRow(int startRow) {        this.startRow = startRow;    }    public int getTotalPageNo() {        return totalPageNo;    }    public void setTotalPageNo(int totalPageNo) {        this.totalPageNo = totalPageNo;    }    public int getDisplayPageNum() {        return displayPageNum;    }    public void setDisplayPageNum(int displayPageNum) {        if(displayPageNum <= 1){            this.displayPageNum = DEF_DISLAY_PAGENUM;        }else{            this.displayPageNum = displayPageNum;        }    }    @Override    public String toString() {        return "Pagination [displayPageNum=" + displayPageNum + ", totalCount="                + totalCount + ", pageSize=" + pageSize + ", pageNo=" + pageNo                + ", pageData=" + pageData + ", startRow=" + startRow                + ", totalPageNo=" + totalPageNo + ", pageNums="                + Arrays.toString(pageNums) + "]";    }    public int[] getPageNums() {        return pageNums;    }    public String getPageSizeName() {        return pageSizeName;    }    public void setPageSizeName(String pageSizeName) {        this.pageSizeName = pageSizeName;    }    public String getPageNoName() {        return pageNoName;    }    public void setPageNoName(String pageNoName) {        this.pageNoName = pageNoName;    }    public String getTotalCountName() {        return totalCountName;    }    public void setTotalCountName(String totalCountName) {        this.totalCountName = totalCountName;    }}

Mybatis的plugin的实现

  • 我这里选择拦截StatementHandler的prepare方法,也就是基本的JDBC中在发出SQL语句之的拦截,这里我们使用根据用户的SQL语句来查出相应的记录的总条数,因为在分页对象中这个参数是很必不可少的。
  • 然后,进行分页(Pagination)参数的计算,当然这些计算已经封装在Pagination对象中。然后,根据计算的结果来进行重构Mybatis发出的SQL语句,也就是分页查询的最终SQL语句,对于Mysql和Orcale对于分页查询的语句是不同的,当然,这需要我们在配置插件的时候,进行指导数据库方言的属性。
  • 对于用户来讲,这一切都是透明的。对于插件,我们都知道,这是在搭建框架的时候,我们总是用抽象的接口来组织逻辑,然后通过配置的方式来增加接口的实现,从而达到了插件的效果。这里进行配置是至关重要的,这里似乎用到AOP的思想,Advice为通知接口为我们自定义接口实现的逻辑方法,配置就相当于Advisor,Pointcut就是切入点。
package com.pcitc.modules.pagination;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Properties;import org.apache.ibatis.executor.parameter.ParameterHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.logging.Log;import org.apache.ibatis.logging.LogFactory;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Plugin;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.reflection.DefaultReflectorFactory;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.ReflectorFactory;import org.apache.ibatis.reflection.factory.DefaultObjectFactory;import org.apache.ibatis.reflection.factory.ObjectFactory;import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;import org.apache.ibatis.session.Configuration;import org.apache.ibatis.session.RowBounds;/** * 通过拦截<code>StatementHandler</code>的<code>prepare</code>方法,重写sql语句实现物理分页。 * 老规矩,签名里要拦截的类型只能是接口。 *  * @author 湖畔微风 *  */@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})public class PageInterceptor implements Interceptor {    private static final Log logger = LogFactory.getLog(PageInterceptor.class);    private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();    private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();    private static final ReflectorFactory DEFAULT_OBJECT_REFLECT_FACTORY = new DefaultReflectorFactory();    private static String defaultDialect = "mysql"; // 数据库类型(默认为mysql)    private static String dialect = ""; // 数据库类型(默认为mysql)    @Override    public Object intercept(Invocation invocation) throws Throwable {        //只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的MappedStatement的sql        //进行Threadlocal进行分页参数的提取        Pagination<Object> page  =  PaginationManager.getPagination();        //若不存在分页参数        if(null == page){             //将执行权交给下一个拦截器            PaginationManager.remove();            return invocation.proceed();        }        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();        MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY,                DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_OBJECT_REFLECT_FACTORY);        // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环可以分离出最原始的的目标类)        while (metaStatementHandler.hasGetter("h")) {            Object object = metaStatementHandler.getValue("h");            metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_OBJECT_REFLECT_FACTORY);        }        // 分离最后一个代理对象的目标类        while (metaStatementHandler.hasGetter("target")) {            Object object = metaStatementHandler.getValue("target");            metaStatementHandler = MetaObject.forObject(object, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_OBJECT_REFLECT_FACTORY);        }        Configuration configuration = (Configuration) metaStatementHandler.getValue("delegate.configuration");        if(null != configuration.getVariables()){            dialect = configuration.getVariables().getProperty("dialect"); //设置数据库方言,默认为mysql        }        if (null == dialect || "".equals(dialect)) {            logger.warn("Property dialect is not setted,use default 'mysql' ");            dialect = defaultDialect;        }       MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");       BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");       String sql = boundSql.getSql();       // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数       Connection connection = (Connection) invocation.getArgs()[0];       // 重设分页参数里的总页数等,若没有totalCount的数值       if(page.getTotalCount() <= 0){           setPagination(sql, connection, mappedStatement, boundSql, page);       }       page.adjustAllProcess(); //进行参数的调整       // 重写sql       String pageSql = buildPageSql(sql, page);       metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);       metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);       metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);       // 将执行权交给下一个拦截器       return invocation.proceed();    }    /**     * 从数据库里查询总的记录数并计算总页数,回写进分页参数<code>Pagination</code>,这样调用者就可用通过 分页参数     * <code>Pagination</code>获得相关信息。     *      * @param sql     * @param connection     * @param mappedStatement     * @param boundSql     * @param page     */    private void setPagination(String sql, Connection connection, MappedStatement mappedStatement,            BoundSql boundSql, Pagination<Object> 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);        } 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);            }        }    }    /**     * 对SQL参数(?)设值     *      * @param ps     * @param mappedStatement     * @param boundSql     * @param parameterObject     * @throws SQLException     */    private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql,            Object parameterObject) throws SQLException {        ParameterHandler parameterHandler = new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);        parameterHandler.setParameters(ps);    }    /**     * 根据数据库类型,生成特定的分页sql     *      * @param sql     * @param page     * @return     */    private String buildPageSql(String sql, Pagination<Object> page) {        if (page != null) {            StringBuilder pageSql = new StringBuilder();            if ("mysql".equals(dialect)) {                pageSql = buildPageSqlForMysql(sql, page);            } else if ("oracle".equals(dialect)) {                pageSql = buildPageSqlForOracle(sql, page);            } else {                return sql;            }            return pageSql.toString();        } else {            return sql;        }    }    /**     * mysql的分页语句     *      * @param sql     * @param page     * @return String     */    public StringBuilder buildPageSqlForMysql(String sql, Pagination<Object> page) {        StringBuilder pageSql = new StringBuilder(100);        String beginrow = String.valueOf(page.getStartRow());        pageSql.append(sql);        pageSql.append(" limit " + beginrow + "," + page.getPageSize());        return pageSql;    }    /**     * 参考hibernate的实现完成oracle的分页     *      * @param sql     * @param page     * @return String     */    public StringBuilder buildPageSqlForOracle(String sql, Pagination<Object> page) {        StringBuilder pageSql = new StringBuilder(100);        pageSql.append("select * from ( select temp.*, rownum row_id from ( ");        pageSql.append(sql);        pageSql.append(" ) temp where rownum <= ").append(page.getPageNo() * page.getPageSize());        pageSql.append(") where row_id > ").append(page.getStartRow());        return pageSql;    }    @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) {    }}

Filter的实现

  • 这里通过Filter的配置来进行,需要分页的URL的定位,因为对于分页来讲我们需要进入同一个URL来进行取出数据库中不同位置的数据而已,只是需要传递不同的参数,如页码。
  • 在Filter方法中,我们首先进行分页对象的初建立,并将其放入到ThreadLocal中,这样是为了mybatis中分页插件,能够拿到分页的部分参数,通过判断是否是用户第一次进入分页页码,来判断是否需要发出来统计分页总的记录数的语句。如需要发出总记录数相应的SQL语句,然后进行重构分页对象。
  • 而且在doFilterChain方法后面需要释放,ThreadLocal中的线程变量,这里是至关重要的。
  • 为什么要释放线程变量?(大坑)
    因为我们知道Tomcat的架构,对于不同的请求是不同的线程来进行处理的,会给我们一个实现的接口servlet或者Filter来进行业务的处理。这里,tomcat的线程不是进行new出来的,因为对于new的操作需要耗费资源,这里采用的是线程池的方式,同样的思想体现于Datasource中。假如,一个线程池中有20个线程(这里可通过tomcat配置文件进行配置),时间上不同的请求可能用的是同一个线程池中某一个线程。那么,上一个线程存放的线程变量就可能被下一个线程取到相应的数据,所以我们需要在一个线程结束的时候,进行线程变量的清楚。
package com.pcitc.modules.pagination;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;public class PaginationFilter implements Filter {      public static String PAGE_SIZE = "pageSize";       public static String PAGE_NO = "pageNo";       public static String TOTAL_COUNT = "totalCount";       private String pageSizeName = PAGE_SIZE;       private String pageNoName = PAGE_NO;       private String totalCountName = TOTAL_COUNT;    @Override    public void init(FilterConfig filterConfig) throws ServletException {    }    @Override    public void destroy() {    }    @Override    public void doFilter(ServletRequest request, ServletResponse response,            FilterChain filterChain) throws IOException, ServletException {          System.out.println("分页插件,过滤器开始");          Integer pageSize = Integer.valueOf((request.getParameter(pageSizeName) == null)?"0":request.getParameter(pageSizeName));          Integer pageNo = Integer.valueOf(request.getParameter(pageNoName) == null?"0":request.getParameter(pageNoName));          Integer totalCount = Integer.valueOf(request.getParameter(totalCountName)== null?"0":request.getParameter(totalCountName));          Pagination<Object> pagination = new Pagination<Object>();          pagination.setPageNoName(pageNoName);          pagination.setPageSizeName(pageSizeName);          pagination.setTotalCountName(totalCountName);          pagination.setPageSize(pageSize);          pagination.setPageNo(pageNo);          pagination.setTotalCount(totalCount);          PaginationManager.setPagination(pagination);          filterChain.doFilter(request, response);          System.out.println("释放ThreadLoca中的值");          PaginationManager.remove();    }}

自定义JSP标签的实现

  • 因为分页的HTML和CSS我们不能控制,为了减少代码侵入性,我们采用给标签中提供相应的分页信息,来让前端人员来自己对样式和dom结构的定义。
package com.pcitc.modules.pagination;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class PaginationTag extends SimpleTagSupport{    public static String COMMON = "common"; //页码组信息    public static String PREPAGE = "prePage"; //前一页信息    public static String POSTPAGE = "postPage"; //后一页信息    private String searchUrl;    private String pageType = COMMON; //判断是否是首页或者尾页    @Override    public void doTag() throws JspException, IOException{          //循环遍历页面显示页码数        Pagination<Object> pagination = PaginationManager.getPagination();        if(pagination != null){            int[] pageNums = pagination.getPageNums();            if("common".equals(pageType)){                for(int i=0;i<pageNums.length;i++){                    String url = this.searchUrl;                    if(!searchUrl.contains("?")){                        url = url + "?";                    }                    url = url + "&" + pagination.getPageSizeName() + "=" + pagination.getPageSize()                            + "&" + pagination.getPageNoName() + "=" + pageNums[i]                            + "&" + pagination.getTotalCountName() + "=" + pagination.getTotalCount();                    //将分页的URL和pageNum设置到page 范围                    getJspContext().setAttribute("pageUrl",url);                     getJspContext().setAttribute("pageNum", pageNums[i]);                     getJspContext().setAttribute("pageInfo", pagination);                    //输出标签体                      getJspBody().invoke(null);                }            }else{                if(pageNums.length > 1){                    if(PREPAGE.equals(pageType)){                        String url = this.searchUrl;                        if(!searchUrl.contains("?")){                            url = url + "?";                        }                        url = url + "&" + pagination.getPageSizeName() + "=" + pagination.getPageSize()                                + "&" + pagination.getPageNoName() + "=" + pagination.getPrePage()                                + "&" + pagination.getTotalCountName() + "=" + pagination.getTotalCount();                        //将分页的URL和pageNum设置到page 范围                        getJspContext().setAttribute("pageUrl",url);                         getJspContext().setAttribute("pageNum", pagination.getPrePage());                        getJspContext().setAttribute("pageInfo", pagination);                        //输出标签体                          getJspBody().invoke(null);                      }else if(POSTPAGE.equals(pageType)){                        String url = this.searchUrl;                        if(!searchUrl.contains("?")){                            url = url + "?";                        }                        url = url + "&" + pagination.getPageSizeName() + "=" + pagination.getPageSize()                                + "&" + pagination.getPageNoName() + "=" + pagination.getNextPage()                                + "&" + pagination.getTotalCountName() + "=" + pagination.getTotalCount();                        //将分页的URL和pageNum设置到page 范围                        getJspContext().setAttribute("pageUrl",url);                         getJspContext().setAttribute("pageNum", pagination.getNextPage());                         getJspContext().setAttribute("pageInfo", pagination);                        //输出标签体                          getJspBody().invoke(null);                        }else{                        String url = this.searchUrl;                        if(!searchUrl.contains("?")){                            url = url + "?";                        }                        url = url + "&" + pagination.getPageSizeName() + "=" + pagination.getPageSize()                                + "&" + pagination.getTotalCountName() + "=" + pagination.getTotalCount()                                + "&" + pagination.getPageNoName() + "=";                        //将分页的URL的元素设置到page 范围                         getJspContext().setAttribute("pageUrl",url);                          getJspContext().setAttribute("pageInfo", pagination);                          //输出标签体                           getJspBody().invoke(null);                      }                }            }        }     }      public String getSearchUrl() {        return searchUrl;    }    public void setSearchUrl(String searchUrl) {        this.searchUrl = searchUrl;    }    public String getPageType() {        return pageType;    }    public void setPageType(String pageType) {        this.pageType = pageType;    }}

tld文件:

<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"    version="2.1">  <description>JSTL 1.1 core library</description>  <display-name>JSTL core</display-name>  <tlib-version>1.1</tlib-version>  <short-name>util</short-name>  <uri>http://ctbu.com/liumi</uri>  <!-- 标签展示通用类 -->  <tag>    <name>page</name>    <tag-class>com.pcitc.web.controller.common.PaginationTag</tag-class>    <body-content>scriptless</body-content>    <!-- 标签体中可以取出pageUrl,pageNum,pageInfo对象用来页面的展示和判断 -->    <attribute>      <name>searchUrl</name>      <required>true</required>      <rtexprvalue>true</rtexprvalue>      <type>java.lang.String</type>    </attribute>    <attribute>      <name>pageType</name>      <required>false</required>      <rtexprvalue>true</rtexprvalue>      <type>java.lang.String</type>      <description>common--代表显示的页码,prePage代表上一页信息,postPage代表下一页信息</description>    </attribute>  </tag></taglib>

JSP使用标签的简单实例:

<!--这里需要web.xml文件中引入相应utl文件位置--><%@ taglib  uri="http://ctbu.com/liumi" prefix="util"%><util:page searchUrl="${ctx}/news/list" pageType="other">这里相当于通过pageType属性来获取相应的分页的信息:other:则是获取分页的信息common:会进行所有显示在页面页码的迭代出不同URL,        通过${pageUrl}来获取prePage和postPage:进行前页和后页信息的获取        显示第 ${pageInfo.startRow+1} 至             ${pageInfo.startRow+listSize} 项结果,共         ${pageInfo.totalCount} 项</util:page>    <--上一页-->     <util:page searchUrl="${ctx}/news/list" pageType="prePage">  <c:if test="${pageInfo.totalCount > pageInfo.pageSize}">    <li id="" class="paginate_button previous">         <a href="${pageUrl}">上页</a>        </li> </c:if></util:page><!--所有页码--><util:page searchUrl="${ctx}/news/list" pageType="common">  <c:if test="${pageInfo.totalCount > pageInfo.pageSize}">   <li class="paginate_button <c:if test='${pageInfo.pageNo == pageNum}'>active</c:if>">        <a href="${pageUrl}">${pageNum}</a>  </li> </c:if></util:page><!--后一页--><util:page searchUrl="${ctx}/news/list" pageType="postPage"><c:if test="${pageInfo.totalCount > pageInfo.pageSize}">    <li id="" class="paginate_button next">    <a tabindex="0" data-dt-idx="8" aria-controls="userTabel" href="${pageUrl}">下页</a>    </li>                   </c:if></util:page>

ThreadLocal来进行Filter到JSP中分页对象传递

package com.pcitc.modules.pagination;/** * 将分页数据进行线程级别传递 * @author mi * */public class PaginationManager {     //使用ThreadLocal保存Connection变量      private static final ThreadLocal<Pagination<Object>> pageHolder = new ThreadLocal<Pagination<Object>>();     public static Pagination<Object> getPagination(){        //ThreadLocal取得当前线程的分页数据        return pageHolder.get();    }    public static void setPagination(Pagination<Object> pagination){        pageHolder.set(pagination);    }    public static void remove(){        pageHolder.remove();    }}

使用说明

  • 在web.xml中进行对Filter的配置,主要是对那个URL进行分页的
    拦截,和对tld文件的引入(jar包中meta文件中tld文件不用引入):
<filter>        <filter-name>paginationFilter</filter-name>        <filter-class>            com.pcitc.modules.pagination.PaginationFilter        </filter-class>    </filter>    <filter-mapping>        <filter-name>paginationFilter</filter-name>        <url-pattern>/news/list</url-pattern>        <dispatcher>REQUEST</dispatcher>        <dispatcher>FORWARD</dispatcher>    </filter-mapping>  <jsp-config>    <taglib>          <taglib-uri>http://ctbu.com/liumi</taglib-uri>          <taglib-location>/WEB-INF/util.tld</taglib-location>    </taglib>    </jsp-config>
  • 配置mybatis拦截器
<plugins><plugin interceptor="com.pcitc.modules.pagination.PageInterceptor">   <!-- 或者mysql -->   <property name="dialect" value="oracle"/></plugin></plugins>
  • 在JSP表中引入:
<%@ taglib  uri="http://ctbu.com/liumi" prefix="util"%>
0 0