【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 
  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);
  }
}

  

回到顶部

运行实例图

暂无