Thymeleaf Maven+Servlet+Mysql图书框架—4(十)

一、实现图书的分页

1、前端Thymeleaf分页模板

html 复制代码
<!--
    number 页码从1开始,如:1,2,3,...
    offset 页码偏移量。如果页码是从0开始,则偏移量为-1;如果页码从1开始,偏移量为0
    totalPages 总页数
    url 地址  如:/my , /my?id=1, /my/book?id=1&limit=10
    1、会自动向url中添加页码,如:/your?id=1&page=1, /your/book?id=1&limit=10&page=1
    2、当超过totalPages>maxButtons时,会显示...代替多余的按钮
    3、maxButtons>=floatButtons*2
-->
<ul class="pagination" th:fragment="page_pager(number, offset, totalPages, url)" th:with="maxButtons=10,floatButtons=5" xmlns:th="http://www.thymeleaf.org">
    <style>
        .pagination {
            display: inline-block;
            padding-left: 300px;
            margin: 20px 0;
            border-radius: 4px
        }

        .pagination > li {
            display: inline
        }

        .pagination > li > a, .pagination > li > span {
            position: relative;
            float: left;
            padding: 6px 12px;
            margin-left: -1px;
            line-height: 1.42857143;
            color: #337ab7;
            text-decoration: none;
            background-color: #fff;
            border: 1px solid #ddd
        }

        .pagination > li:first-child > a, .pagination > li:first-child > span {
            margin-left: 0;
            border-top-left-radius: 4px;
            border-bottom-left-radius: 4px
        }

        .pagination > li:last-child > a, .pagination > li:last-child > span {
            border-top-right-radius: 4px;
            border-bottom-right-radius: 4px
        }

        .pagination > li > a:focus, .pagination > li > a:hover, .pagination > li > span:focus, .pagination > li > span:hover {
            z-index: 2;
            color: #23527c;
            background-color: #eee;
            border-color: #ddd
        }

        .pagination > .active > a, .pagination > .active > a:focus, .pagination > .active > a:hover, .pagination > .active > span, .pagination > .active > span:focus, .pagination > .active > span:hover {
            z-index: 3;
            color: #fff;
            cursor: default;
            background-color: #337ab7;
            border-color: #337ab7
        }

        .pagination > .disabled > a, .pagination > .disabled > a:focus, .pagination > .disabled > a:hover, .pagination > .disabled > span, .pagination > .disabled > span:focus, .pagination > .disabled > span:hover {
            color: #777;
            cursor: not-allowed;
            background-color: #fff;
            border-color: #ddd
        }

        .pagination-lg > li > a, .pagination-lg > li > span {
            padding: 10px 16px;
            font-size: 18px;
            line-height: 1.3333333
        }

        .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span {
            border-top-left-radius: 6px;
            border-bottom-left-radius: 6px
        }

        .pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span {
            border-top-right-radius: 6px;
            border-bottom-right-radius: 6px
        }

        .pagination-sm > li > a, .pagination-sm > li > span {
            padding: 5px 10px;
            font-size: 12px;
            line-height: 1.5
        }

        .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span {
            border-top-left-radius: 3px;
            border-bottom-left-radius: 3px
        }

        .pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span {
            border-top-right-radius: 3px;
            border-bottom-right-radius: 3px
        }
    </style>

    <!-- 上一页 -->
    <li th:if="${number == 1}"><span>上一页</span></li>
    <li th:if="${number > 1}"><a th:href="@{${url}(pageNum=${number+offset-1})}">上一页</a></li>

    <!-- 首页 -->
    <li th:if="${number == 1}" class="active"><span>1</span></li>
    <li th:if="${number > 1}"><a th:href="@{${url}(pageNum=${1+offset})}">1</a></li>

    <th:block th:if="${totalPages>2 && totalPages<=maxButtons}" th:each="i : ${#numbers.sequence(2,totalPages-1)}">
        <li th:if="${number == i}" class="active"><span th:text="${i}">页码</span></li>
        <li th:if="${number != i}"><a th:href="@{${url}(pageNum=${i+offset})}" th:text="${i}">页码</a></li>
    </th:block>

    <th:block th:if="${totalPages > maxButtons}">
        <th:block th:if="${(number-(floatButtons/2)) <= 2}" th:each="i : ${#numbers.sequence(2,2+floatButtons-1)}">
            <li th:if="${number == i}" class="active"><span th:text="${i}">页码</span></li>
            <li th:if="${number != i}"><a th:href="@{${url}(pageNum=${i+offset})}" th:text="${i}">页码</a></li>
        </th:block>
        <!-- ... -->
        <li th:if="${(number-(floatButtons/2))>2}"><span>...</span></li>

        <th:block th:if="${((number-(floatButtons/2))>2) && ((number+(floatButtons/2)-(floatButtons%2==0?1:0)) < (totalPages-1))}"
                  th:each="i : ${#numbers.sequence(number-(floatButtons/2),number+(floatButtons/2)-(floatButtons%2==0?1:0))}">
            <li th:if="${number == i}" class="active"><span th:text="${i}">页码</span></li>
            <li th:if="${number != i}"><a th:href="@{${url}(pageNum=${i+offset})}" th:text="${i}">页码</a></li>
        </th:block>

        <!-- ... -->
        <li th:if="${(number+(floatButtons/2)-(floatButtons%2==0?1:0)) < (totalPages-1)}"><span>...</span></li>
        <th:block th:if="${(number+(floatButtons/2)-(floatButtons%2==0?1:0)) >= (totalPages-1)}" th:each="i : ${#numbers.sequence(totalPages-floatButtons,totalPages-1)}">
            <li th:if="${number == i}" class="active"><span th:text="${i}">页码</span></li>
            <li th:if="${number != i}"><a th:href="@{${url}(pageNum=${i+offset})}" th:text="${i}">页码</a></li>
        </th:block>
    </th:block>

    <!-- 最后一页 -->
    <li th:if="${totalPages>1 && number == totalPages}" class="active"><span th:text="${totalPages}">页码</span></li>
    <li th:if="${totalPages>1 && number != totalPages}"><a th:href="@{${url}(pageNum=${totalPages+offset})}" th:text="${totalPages}">页码</a></li>

    <!-- 下一页 -->
    <li th:if="${number >= totalPages}"><span>下一页</span></li>
    <li th:if="${number < totalPages}"><a th:href="@{${url}(pageNum=${number+offset+1})}">下一页</a></li>
</ul>

2、后端PageBean封装

java 复制代码
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class PageBean <T>{
    // 当前页码
    private int currentPage=1;
    // 每页显示条数
    private int pageSize=4;
    // 总页数
    private int totalPage;
    // 总记录数
    private int totalCount;
    // 当前页数据
    private List<T> records;

    public PageBean(int currentPage, int pageSize, int totalCount, List<T> records) {
        this.currentPage = currentPage;
        this.pageSize = pageSize;
        this.totalCount = totalCount;
        this.records = records;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
        // 计算总页数
        this.totalPage = totalCount % pageSize == 0 ? (totalCount / pageSize) : (totalCount / pageSize + 1);

    }
}

3、后端底层Dao操作数据库

java 复制代码
   public List<Books> queryByPage(int pageNum, int pageSize, Books books) throws Exception {
        String sql = "select id,title,author,isbn,stock,publish_date publishDate,category from books order by id limit ?,? ";
        return executeQuery(Books.class,sql,(pageNum-1)*pageSize,pageSize);
    }

分析:(当前页-1)*每页个数

java 复制代码
-- one   (1-1)*4
select  * from books where title like '%%' or author like '%%' limit 0,4

-- two  (2-1)*4
select  * from books where title like '%%' or author like '%%' limit 4,4


-- three  (3-1)*4
select  * from books where title like '%%' or author like '%%' limit 8,4


-- four  (4-1)*4
select  * from books where title like '%%' or author like '%%' limit 12,4


-- five  (5-1)*4
select  * from books where title like '%%' or author like '%%' limit 16,4

4、业务层Service调Dao层

java 复制代码
   @Override
    public List<Books> findByPage(int pageNum, int pageSize, Books books) throws Exception {
        return booksDao.queryByPage(pageNum,pageSize,books);
    }

5、控制层Servlet调用Service层

java 复制代码
 public void findPage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        CustomTemplateEngine engine = CustomTemplateEngine.getInstance(req);
        try {

            // 获取当前页码
            String strPageNum = req.getParameter("pageNum");
            //判断当前页码是否小于1
            int pageNum = (strPageNum == null || strPageNum.equals("")) ? 1 : Integer.parseInt(strPageNum);

            // 每页显示条数
           int pageSize = 4;

            // 获取书籍总个数
            int totalCount = booksService.findBook().size();

            // 查询书籍信息
            List<Books> books = booksService.findByPage(pageNum, pageSize, null);

            // 封装分页信息
            PageBean<Books> pageBean = new PageBean(pageNum, pageSize, totalCount, books);
            // 计算总页数
            pageBean.setTotalPage(totalCount);

           // System.out.println("pageBean=>>>" + pageBean);

            // 将书籍信息保存到request域中
            req.setAttribute("books", pageBean);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // 转发到list.html页面
        engine.processTemplate("book/list", req, resp);

    }

6、运行效果

相关推荐
翼龙云_cloud2 小时前
亚马逊云渠道商:RDS 三大数据库引擎深度对比 MySQL/PostgreSQL/SQL Server 如何选?
数据库·mysql·postgresql·aws
人道领域2 小时前
javaWeb从入门到进阶(MYSQL)
数据库·mysql·oracle
liux35282 小时前
MySQL读写分离全面解析:ProxySQL配置指南(十)
数据库·mysql
heze092 小时前
sqli-labs-Less-24
mysql·网络安全
csdn_aspnet3 小时前
用 MySQL 玩转数据可视化:从底层数据到 BI 工具的桥接
数据库·mysql·信息可视化·bi
secondyoung3 小时前
队列原理与实现全解析
c语言·数据库·mysql·算法·队列
Yorlen_Zhang4 小时前
Python pytest assert 断言
python·servlet·pytest
悟能不能悟4 小时前
mysql主键递增,之前已经插入的id有1,2,3,4,5,手动插入的那条记录id=15,那后面让它自动生成主键,会是从15开始,还是从5开始
数据库·mysql
代码丰4 小时前
实际例子理解Redis 缓存与 MySQL 数据一致性 以及常见的细节
redis·mysql·缓存