• 【Bootstrap】Bootstrap和Java分页-第一篇


     

    目录

    关于此文

      bootstrap是前端很流行的框架,正在开发的项目,用bootstrap搭建起来的页面,自我感觉很完美,终于告别了苦逼坑爹苍白无力的白花花的难看的……的页面了。哈哈。

         现在遇到了bootstrap的分页与Java后台结合起来的分页封装问题,对于我这个Java菜鸟来说,包装分页还没玩过。故此,在网上找了这个。觉得很不错,所以决定记录到博客里面。

         还没有实践,决定写完博客去实践。在上图。祝我成功吧!

         此人的博客没找到,代码中有email地址。此文转自:super.wwz@hotmail.com

    pagination

    定义了分页常用的属性,方法

    package com.app.pagination;
    import java.util.List;
    /**
     * 通用分页接口
     * @author: super.wwz@hotmail.com
     * @ClassName: Pagination
     * @Version: v0.1
     * @param <T>
     */  
    public interface Pagination<T> {
        /**
         * 判断是否是首页
         * @return
         */
        boolean isFirst();
        /**
         * 判断是否是尾页
         * @return
         */
        boolean isLast();
        /**
         * 判断是否有上一页
         * @return
         */
        boolean isPrevious();
        /**
         * 判断是否有下一页
         * @return
         */
        boolean isNext();
        
        
        /**
         * 获取上一页的页码
         * @return
         */
        int getPreviousIndex();
        /**
         * 获取下一页的页码
         * @return
         */
        int getNextIndex();
        /**
         * 获取当前页码
         * @return
         */
        int getPageIndex();
        /**
         * 获取当前页大小
         * @return
         */
        int getPageSize();
        /**
         * 获取总页数
         * @return
         */
        int getTotalPages();
        /**
         * 获取数据总行数
         * @return
         */
        int getTotalElements();
        
        /**
         * 获取当前页的数据
         * @return
         */
        List<T> getCurrData();
        
        /**
         * 获取数字分页链接对象
         * @return
         */
        BetweenIndex getBetweenIndex();
        
        /**
         * 获取每页显示的分页链接数
         * @return
         */
        int getPageLinkNumber();
        
        /**
         * 设置每页的分页链接数量
         * @param pageLinkNumber
         */
        void setPageLinkNumber(int pageLinkNumber);
    }
    

    BetweenIndex

    该接口负责获取分页链接的开始和结尾索引

    package com.app.pagination;
    /**
     * 开始链接-结束链接
     * @author: super.wwz@hotmail.com
     * @ClassName: BetweenIndex
     * @Version: v0.1
     */
    public interface BetweenIndex {
        /**
         * 获取开始分页链接索引
         * @return
         */
        int getBeginIndex();
        /**
         * 获取结束分页链接索引
         * @return
         */
        int getEndIndex();
    }
    

      

    DefaultPagination

    Pagination接口的默认实现类

    package com.app.pagination.impl;
    import java.util.List;
    import com.app.pagination.BetweenIndex;
    import com.app.pagination.Pagination;
    /**
     * Pagination接口默认实现
     * @author: super.wwz@hotmail.com
     * @ClassName: DefaultPagination
     * @Version: v0.1
     * @param <T>
     */
    public class DefaultPagination<T> implements Pagination<T> {
      private int totalElements;
      private int pageSize;
      private int totalPages;
      private int pageIndex;
      private QueryHandler<T> queryHandler;
      private List<T> currData;
      private int pageLinkNumber;
      public DefaultPagination(int pageIndex, int pageSize, QueryHandler<T> queryHandler, int pageLinkNumber) {
        this(pageIndex, pageSize, queryHandler);
        setPageLinkNumber(pageLinkNumber);
      }
      public DefaultPagination(int pageIndex, int pageSize, QueryHandler<T> queryHandler){
        //初始化数据访问回调接口
        this.queryHandler = queryHandler;
        //查询总行数
        setTotalElements();
        //修正页大小
        setPageSize(pageSize);
        //计算总页数:
        setTotalPages();
        //修正页码
        setPageIndex(pageIndex);
        //查询当前页数据
        setCurrData();
      }
      private void setCurrData() {
        // TODO Auto-generated method stub
        this.currData = queryHandler.getCurrData(pageIndex, pageSize);
      }
      private void setPageIndex(int pageIndex) {
        // TODO Auto-generated method stub
        if(pageIndex < 1) {
          this.pageIndex  = 1;
        } else if(pageIndex > totalPages) {
          this.pageIndex = totalPages;
        } else {
          this.pageIndex = pageIndex;
        }
      }
      private void setTotalPages() {
        // TODO Auto-generated method stub
        if(pageSize > 0) {
          /*//普通算法: 
          this.totalPages = totalElements % pageSize == 0 ? 
              totalElements / pageSize : (totalElements / pageSize) + 1;*/
          //减一公式:
          this.totalPages = (totalElements + pageSize - 1) / pageSize;
        }
      }
      private void setPageSize(int pageSize) {
        // TODO Auto-generated method stub
        if(pageSize < 1) {
          this.pageSize = 1;
        } else if(pageSize > totalElements) {
          this.pageSize = totalElements;
        } else {
          this.pageSize = pageSize;
        }
      }
      private void setTotalElements() {
        // TODO Auto-generated method stub
        this.totalElements = queryHandler.getTotalElements();
      }
      @Override
      public boolean isFirst() {
        // TODO Auto-generated method stub
        return pageIndex == 1;
      }
      @Override
      public boolean isLast() {
        // TODO Auto-generated method stub
        return pageIndex == totalPages;
      }
      @Override
      public boolean isPrevious() {
        // TODO Auto-generated method stub
        return pageIndex > 1;
      }
      @Override
      public boolean isNext() {
        // TODO Auto-generated method stub
        return pageIndex < totalPages;
      }
      @Override
      public int getPreviousIndex() {
        // TODO Auto-generated method stub
        return isPrevious() ? pageIndex - 1 : 1;
      }
      @Override
      public int getNextIndex() {
        // TODO Auto-generated method stub
        return isNext() ? pageIndex + 1 : totalPages;
      }
      @Override
      public int getPageIndex() {
        // TODO Auto-generated method stub
        return pageIndex;
      }
      @Override
      public int getPageSize() {
        // TODO Auto-generated method stub
        return pageSize;
      }
      @Override
      public int getTotalPages() {
        // TODO Auto-generated method stub
        return totalPages;
      }
      @Override
      public int getTotalElements() {
        // TODO Auto-generated method stub
        return totalElements;
      }
      @Override
      public List<T> getCurrData() {
        // TODO Auto-generated method stub
        return currData;
      }
      @Override
      public BetweenIndex getBetweenIndex() {
        // TODO Auto-generated method stub
        return new BetweenIndex() {
          private int beginIndex;
          private int endIndex;
          {
            boolean isOdd = pageLinkNumber % 2 == 0;
            int val = pageLinkNumber / 2;
            beginIndex = pageIndex - (isOdd ? val - 1: val);
            endIndex = pageIndex + val;
            if(beginIndex < 1) {
              beginIndex  = 1;
              endIndex = pageLinkNumber;
            }
            if(endIndex > totalPages) {
              endIndex = totalPages;
              beginIndex = endIndex - pageLinkNumber + 1;
            }
          }
          @Override
          public int getEndIndex() {
            // TODO Auto-generated method stub
            return endIndex;
          }
          @Override
          public int getBeginIndex() {
            // TODO Auto-generated method stub
            return beginIndex;
          }
        };
      }
      @Override
      public int getPageLinkNumber() {
        // TODO Auto-generated method stub
        return pageLinkNumber;
      }
      @Override
      public void setPageLinkNumber(int pageLinkNumber) {
        // TODO Auto-generated method stub
        if (pageLinkNumber < 0) {
          this.pageLinkNumber = 0;
        } else if (pageLinkNumber > totalPages) {
          this.pageLinkNumber = totalPages;
        } else {
          this.pageLinkNumber = pageLinkNumber;
        }
      }
    }
    

      

    QueryHandler

    用于DefaultPagination实现类的查询回调接口

    package com.app.pagination.impl;
    import java.util.List;
    /**
     * 分页查询回调接口
     * @author: super.wwz@hotmail.com
     * @ClassName: QueryHandler
     * @Version: v0.1
     * @param <T>
     */
    public interface QueryHandler<T> {
        /**
         * 获取数据总行数
         * @return
         */
        int getTotalElements();
        
        /**
         * 获取当前页的数据
         * @param pageIndex
         * @param pageSize
         * @return
         */
        List<T> getCurrData(int pageIndex, int pageSize);
    }
    

      

    BookDaoImpl

    BookDao的实现类(BookDao接口已经省略)

    package com.app.dao.impl;
    import java.sql.SQLException;
    import java.util.List;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.ScalarHandler;
    import com.app.bean.Book;
    import com.app.dao.BaseDao;
    import com.app.dao.BookDao;
    public class BookDaoImpl extends BaseDao implements BookDao {
      @Override
      public int count() {
        // 查询数据总行数
        String sql = "select count(1) from t_book";
        try {
          return getQueryRunner().query(sql, new ScalarHandler<Integer>());
        } catch (SQLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        return 0;
      }
      @Override
      public List<Book> getBooks(int pageIndex, int pageSize) {
        // 关于SQLServer的查询分页sql
        StringBuffer sql = new StringBuffer();
        sql.append("select * from (");
        sql.append("	select row_number() over(order by(id)) new_id,* from t_book");
        sql.append(") t where new_id between ? and ?");
        try {
          return getQueryRunner().query(sql.toString(),
              new BeanListHandler<Book>(Book.class), 
                pageSize * (pageIndex - 1) + 1,pageSize * pageIndex);
        } catch (SQLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        return null;
      }
    }
    

      

    BookServiceImpl

    BookService业务逻辑接口的实现类 (BookService已经省略)

    package com.app.service.impl;
    import java.util.List;
    import com.app.bean.Book;
    import com.app.dao.BookDao;
    import com.app.dao.impl.BookDaoImpl;
    import com.app.pagination.Pagination;
    import com.app.pagination.impl.DefaultPagination;
    import com.app.pagination.impl.QueryHandler;
    import com.app.service.BookService;
    /**
     * 业务逻辑层查询分页数据示例
     * @author: super.wwz@hotmail.com
     * @ClassName: BookServiceImpl
     * @Version: v0.1
     */
    public class BookServiceImpl implements BookService {
      private BookDao bookDao = new BookDaoImpl();
      @Override
      public Pagination<Book> getBookList(int pageIndex, int pageSize,int pageLinkNumber) {
        // TODO Auto-generated method stub
        return new DefaultPagination<Book>(pageIndex, pageSize, new QueryHandler<Book>() {
          @Override
          public int getTotalElements() {
            // TODO Auto-generated method stub
            return bookDao.count();
          }
          @Override
          public List<Book> getCurrData(int pageIndex, int pageSize) {
            // TODO Auto-generated method stub
            return bookDao.getBooks(pageIndex, pageSize);
          }
        },pageLinkNumber);
      }
    }
    

      

    BookAction

    有关图书的Servlet控制器

    package com.app.web.action;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import com.app.bean.Book;
    import com.app.pagination.Pagination;
    import com.app.service.BookService;
    import com.app.service.impl.BookServiceImpl;
    public class BookAction extends HttpServlet {
      private static final long serialVersionUID = 5275929408058702210L;
      private BookService bookService = new BookServiceImpl();
      @Override
      protected void service(HttpServletRequest request, HttpServletResponse response)
          throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        int pageIndex = 1;
        int pageSize = 10;
        try {
          pageIndex = Integer.parseInt(request.getParameter("pageIndex"));
          pageSize = Integer.parseInt(request.getParameter("pageSize"));
        } catch (NumberFormatException e) {
          e.printStackTrace();
        }
         //6: 显示的分页链接个数
        Pagination<Book> bookPagination = bookService.getBookList(pageIndex, pageSize,6);
        request.setAttribute("bookPagination", bookPagination);
        request.getRequestDispatcher("index.jsp").forward(request, response);
      }
    }
    

      

    Jsp

    index.jsp

    将Pagiation应用到bootstrap上的简单示例bootstrap版本: 3.3.5

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <c:if test="${requestScope.bookPagination == null }">
      <c:redirect url="bookAction?pageIndex=1&pageSize=4"></c:redirect>
    </c:if>
    <!DOCTYPE html">
    <html>
      <head>
        <title>图书信息列表</title>
        <!-- Bootstrap v3.3.5 -->
    <link href="${pageContext.request.contextPath}/bootstrap-3.3.5-dist/css/bootstrap.min.css"
      type="text/css" rel="stylesheet" charset="utf-8" />
    <link id="bootstrapTheme"
      href="${pageContext.request.contextPath}/bootstrap-3.3.5-dist/css/bootstrap-theme.min.css"
      type="text/css" rel="stylesheet" charset="utf-8" />
    <script src="${pageContext.request.contextPath}/bootstrap-3.3.5-dist/js/jquery.min.js"
      type="text/javascript" charset="utf-8"></script>
    <script src="${pageContext.request.contextPath}/bootstrap-3.3.5-dist/js/bootstrap.min.js"
      type="text/javascript" charset="utf-8"></script>
      </head>
      <body>
      <div class="container">
        <h2 class="page-header">图书信息</h2>
        <table class="table table-striped table-bordered table-hover">
          <tr>
            <th>#</th>
            <th>图书名</th>
            <th>单价</th>
          </tr>
          <c:set var="bookPagination" value="${requestScope.bookPagination}"></c:set>
          <c:choose>
            <c:when test="${bookPagination.totalElements gt 0}">
              <c:forEach var="book" items="${bookPagination.currData}">
                <tr>
                  <td>${book.id }</td>
                  <td>${book.name }</td>
                  <td>${book.price }</td>
                </tr>
              </c:forEach>
              <td colspan="3" align="center">
              <div class="btn-group" role="group">
                <c:if test="${bookPagination.first}" var="isFirst">
                  <a class="btn btn-primary btn-sm" disabled="disabled" href="#">首页</a> 
                  <a class="btn btn-success btn-sm" disabled="disabled" href="#">上一页</a>
                </c:if>
                <c:if test="${not isFirst}">
                <a class="btn btn-primary btn-sm" href="${pageContext.request.contextPath}/bookAction?pageIndex=1&pageSize=${bookPagination.pageSize}">首页</a> 
                <a class="btn btn-success btn-sm" href="${pageContext.request.contextPath}/bookAction?pageIndex=${bookPagination.previousIndex }&pageSize=${bookPagination.pageSize}">上一页</a>
                </c:if>
                <c:if test="${bookPagination.last }" var="isLast">
                  <a class="btn btn-success btn-sm" disabled="disabled" href="#">下一页</a> 
                  <a class="btn btn-primary btn-sm" disabled="disabled" href="#">尾页</a>
                </c:if>
                <c:if test="${not isLast}">
                <a class="btn btn-success btn-sm" href="${pageContext.request.contextPath}/bookAction?pageIndex=${bookPagination.nextIndex }&pageSize=${bookPagination.pageSize}">下一页</a> 
                <a class="btn btn-primary btn-sm" href="${pageContext.request.contextPath}/bookAction?pageIndex=${bookPagination.totalPages }&pageSize=${bookPagination.pageSize}">尾页</a>
                </c:if>
                </div>
              </td>
            </c:when>
            <c:otherwise>
              <tr><td colspan="3">没有更多数据!</td></tr>
            </c:otherwise>
          </c:choose>
        </table>
        <center>
          <nav>
          <ul class="pagination">
          <c:if test="${isFirst }">
             <li class="disabled">
              <a href="#" aria-label="Previous">
              <span aria-hidden="true">»上一页</span>
              </a>
            </li>
          </c:if>
          <c:if test="${not isFirst }">
            <li>
              <a href="${pageContext.request.contextPath}/bookAction?pageIndex=${bookPagination.previousIndex }&pageSize=${bookPagination.pageSize}" aria-label="Previous">
              <span aria-hidden="true">»上一页</span>
              </a>
            </li>
          </c:if>
          <c:if test="${bookPagination.pageLinkNumber gt 0}">
            <c:set var="betweenIndex" value="${bookPagination.betweenIndex}"></c:set>
            <c:forEach var="linkIndex" begin="${betweenIndex.beginIndex}" end="${betweenIndex.endIndex}">
              <c:if test="${linkIndex eq  bookPagination.pageIndex}" var="isCurr">
                <li class="active"><a href="#">${linkIndex}</a></li>
              </c:if>
              <c:if test="${not isCurr}">
                <li><a href="${pageContext.request.contextPath}/bookAction?pageIndex=${linkIndex}&pageSize=${bookPagination.pageSize}" >${linkIndex}</a></li>
              </c:if>
            </c:forEach>
          </c:if>
          <c:if test="${isLast }">
             <li class="disabled">
              <a href="#" aria-label="Next">
              <span aria-hidden="true">下一页 »</span>
              </a>
            </li>
          </c:if>
          <c:if test="${not isLast }">
            <li>
              <a href="${pageContext.request.contextPath}/bookAction?pageIndex=${bookPagination.nextIndex }&pageSize=${bookPagination.pageSize}" aria-label="Next">
              <span aria-hidden="true">下一页 »</span>
              </a>
            </li>
          </c:if>
          </ul>
        </nav>
        </center>
      </div>
      </body>
    </html> 
    

      

    实例数据

    说明:

    1. 如果需要扩展分页功能, 请扩展Pagiation接口以及其余实现类;
    2. 此外, 此分页不依赖任何数据库(重新实现QueryHandler查询回调接口即可), 可适用于任何web项目中;

    使用List 集合模拟数据库的使用示例:

    package com.app.service.impl;
    import java.util.ArrayList;
    import java.util.List;
    import com.app.bean.Book;
    import com.app.pagination.Pagination;
    import com.app.pagination.impl.DefaultPagination;
    import com.app.service.BookService;
    /**
     * 使用List<T>集合模拟数据库
     * @author: super.wwz@hotmail.com
     * @ClassName: BookServiceImpl2
     * @Version: v0.1
     */
    public class BookServiceImpl2 implements BookService {
    //	private BookDao bookDao = new BookDaoImpl();
      private static List<Book> list = new ArrayList<Book>();
      //初始化List<Book>数据
      static {
        list.add(new Book(1, "书名1", 18));
        list.add(new Book(2, "书名2", 13));
        list.add(new Book(3, "书名3", 18));
        list.add(new Book(4, "书名4", 38));
        list.add(new Book(5, "书名5", 18));
        list.add(new Book(6, "书名6", 58));
        list.add(new Book(7, "书名7", 12));
        list.add(new Book(8, "书名8", 11));
        list.add(new Book(9, "书名9", 13));
        list.add(new Book(10, "书名10", 22));
        list.add(new Book(11, "书名11", 19));
        list.add(new Book(12, "书名12", 13));
        list.add(new Book(13, "书名13", 19));
        list.add(new Book(14, "书名14", 32));
      }
      @Override
      public Pagination<Book> getBookList(int pageIndex, int pageSize, int pageLinkNumber) {
        return new DefaultPagination<Book>(pageIndex, pageSize, new QueryHandler<Book>() {
          @Override
          public int getTotalElements() {
              //return bookDao.count();
            return list.size();
          }
          @Override
          public List<Book> getCurrData(int pageIndex, int pageSize) {
              //return bookDao.list(pageIndex, pageSize);
            int fromIndex = (pageIndex - 1) * pageSize;
            int endIndex = fromIndex + pageSize;
            endIndex = endIndex > list.size() ? list.size() : endIndex;
            return list.subList(fromIndex, endIndex);
          }
        }, pageLinkNumber);
      }
    }
    

      

    运行实例图

    暂无

  • 相关阅读:
    深入浅出java的Map
    退役划水(7)
    .NET 云原生架构师训练营(模块二 基础巩固 EF Core 关系)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 EF Core 基础与配置)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 EF Core 介绍)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 MySQL环境准备)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 MVC终结点)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 路由与终结点)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 HTTP管道与中间件)--学习笔记
    .NET 云原生架构师训练营(模块二 基础巩固 REST && RESTful)--学习笔记
  • 原文地址:https://www.cnblogs.com/anny0404/p/5124395.html
Copyright © 2020-2023  润新知