学习内容:

分页设计


需求:使用 mybatis 从数据库中查询数据并实现分页功能,大概如下图(没给样式将就看一下,功能实现了就好):

1、分页需传递的参数

  • 需要用户传入的参数:
    1)currentPage:当前页,跳转到第几页,int 类型,设置默认值,比如 1。
    2)pageSize:每页最多多少条数据,int 类型,设置默认值,比如 10。

2、分页需展示的数据

从分页效果图中可以看出,分页需要依赖的数据:
当前页货品信息: data/list
分页条信息:
beginPage: 首页
prevPage: 上一页
nextPage: 下一页
totalPage: 总页数/末页
totalCount/rows: 总条数
currentPage: 当前页
pageSize: 每页显示多少条数据

3、分页需展示的数据的来源

- 来源于用户传入:
currentPage: 当前页,int 类型
pageSize: 每页显示多少条数据,int 类型

  • 来源于两条 SQL 查询:
    totalCount/rows: 数据总条数,int 类型
    data/list: 每一页的结果集数据,List 类型
  • 来源于程序计算:
    totalPage: 总页数/末页,int 类型
    prevPage: 上一页,int 类型
    nextPage: 下一页,int 类型

3.1、结果总数与结果集(分页原理)

结果总数(totalCount/rows)和结果集(data/list)是来源于两条 SQL(必须掌)的查询:

  • 第一条 SQL:查询符合条件的结果总数(totalCount/rows)
SELECT COUNT(*) FROM 表名 [WHERE 条件]
  • 第二条 SQL:查询符合条件的结果集(data/list)
# 第一个 ?:从哪一个索引的数据开始查询(默认从 0 开始)
# 第二个 ?:查询多少条数据
SELECT * FROM 表名 [WHERE 条件] LIMIT ?, ?

接下来分析第二条 SQL 中两个 ? 取值来源:
假设 product 表中有 21 条数据,每页分 5 条数据:
查询第一页数据:SELECT * FROM product LIMIT 0, 5
查询第二页数据:SELECT * FROM product LIMIT 5, 5
查询第三页数据:SELECT * FROM product LIMIT 10, 5
查询第四页数据:SELECT * FROM product LIMIT 15, 5
通过寻找规律发现:第一个 ? 取值来源于 (currentPage - 1) * pageSize;第二个 ? 取值来源于 pageSize,即都来源于用户传递的分页参数。

3.2、总页数、上一页和下一页

总页数、上一页和下一页都是来源于程序计算出来的。

int totalPage = rows % pageSize == 0 ? rows / pageSize : rows / pageSize + 1; // 优先计算
int prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
int nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;

4、分页实现源码(只写重要部分)

4.1、编写 PageResult.java

package com.yy.homework.po;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Getter @Setter @AllArgsConstructor
public class PageResult<T> {
// 用户传入的数据
private int pageSize; // 页面条数
private int currentPage; // 当前页 // 从数据库查询的数据
private int totalCount; // 总条数
private List<T> data; // 当前页结果集数据 // 三个程序计算的数据
private int prevPage; // 上一页
private int nextPage; // 下一页
private int totalPage; // 总页数 public PageResult() {
} public PageResult(int pageSize, int currentPage, int totalCount, List<T> data) {
this.pageSize = pageSize;
this.currentPage = currentPage;
this.totalCount = totalCount;
this.data = data; // 计算三个数据
this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
this.prevPage = currentPage - 1 >= 1 ? currentPage - 1 : 1;
this.nextPage = currentPage + 1 <= totalPage ? currentPage + 1 : totalPage;
}
}

4.2、编写 QueryObject.java

@Setter @Getter @AllArgsConstructor @NoArgsConstructor
public class ProductQuery {
private Integer currentPage = 1;
private Integer pageSize = 3;
public Integer getStart() {
return (currentPage - 1) * pageSize;
}
}

4.3、编写 ProductQueryObject .java

@NoArgsConstructor @AllArgsConstructor @Getter @Setter
public class ProductQueryObject extends ProductQuery {
private String productName;
private BigDecimal minSalePrice;
private BigDecimal maxSalePrice;
}

4.4、编写 ProductMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yy.homework.mapper.ProductMapper">
<select id="select" resultType="Product">
select * from product
where
id = #{id}
</select> <select id="selectAll" parameterType="map" resultType="Product">
select * from product
<include refid="sql_where"/>
limit #{start}, #{pageSize}
</select> <select id="selectCount" resultType="Integer">
select count(*) from product
<include refid="sql_where"/>
</select> <sql id="sql_where">
<where>
<if test="productName != null and productName != ''">
and productName like concat('%', #{productName}, '%')
</if>
<if test="minSalePrice != null">
and salePrice &gt;= #{minSalePrice}
</if>
<if test="maxSalePrice != null">
and salePrice &lt;= #{maxSalePrice}
</if>
</where>
</sql>
</mapper>

4.5、编写 ProductDAOImpl.java

package com.yy.homework.dao.impl;
import com.yy.homework.dao.IProductDAO;
import com.yy.homework.domain.Product;
import com.yy.homework.po.ProductQueryObject;
import com.yy.homework.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; public class ProductDAOImpl implements IProductDAO {
SqlSession session = null;
@Override
public List<Product> selectAll(ProductQueryObject po) {
session = MybatisUtil.getSession();
List<Product> products = session.selectList("com.yy.homework.mapper.ProductMapper.selectAll", po);
session.commit();
session.close();
return products;
}
@Override
public int selectCount(ProductQueryObject po) {
session = MybatisUtil.getSession();
int count = session.selectOne("com.yy.homework.mapper.ProductMapper.selectCount", po);
session.commit();
session.close();
return count;
}
}

4.6、编写 ProductServiceImpl.java

package com.yy.homework.service.impl;

import com.yy.homework.dao.IProductDAO;
import com.yy.homework.dao.impl.ProductDAOImpl;
import com.yy.homework.domain.Product;
import com.yy.homework.po.PageResult;
import com.yy.homework.po.ProductQueryObject;
import com.yy.homework.service.IProductService;
import java.util.List;
import java.util.Map; public class ProductServiceImpl implements IProductService {
private IProductDAO productDAO = new ProductDAOImpl();
@Override
public PageResult<Product> selectAll(ProductQueryObject po) {
int totalCount = productDAO.selectCount(po);
List<Product> products = productDAO.selectAll(po);
return new PageResult<>(po.getPageSize(), po.getCurrentPage(), totalCount, products);
}
}

4.7、编写 ProductServlet.java

package com.yy.homework.web.servlet;
import com.yy.homework.domain.Product;
import com.yy.homework.domain.User;
import com.yy.homework.po.CheckProduct;
import com.yy.homework.po.PageResult;
import com.yy.homework.po.ProductQueryObject;
import com.yy.homework.service.IProductService;
import com.yy.homework.service.impl.ProductServiceImpl;
import com.yy.homework.util.StringUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal; @WebServlet("/product")
public class ProductServlet extends HttpServlet {
private IProductService productService = new ProductServiceImpl(); @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String cmd = req.getParameter("cmd");
System.out.println("cmd = " + cmd);
String id = req.getParameter("id"); ProductQueryObject po = new ProductQueryObject();
String currentPage = req.getParameter("currentPage");
String pageSize = req.getParameter("pageSize");
String productName = req.getParameter("productName");
String minSalePrice = req.getParameter("minSalePrice");
String maxSalePrice = req.getParameter("maxSalePrice"); if (StringUtil.hasLength(pageSize)) {
po.setPageSize(Integer.parseInt(pageSize));
}
if (StringUtil.hasLength(currentPage)) {
po.setCurrentPage(Integer.parseInt(currentPage));
}
if (StringUtil.hasLength(productName)) {
po.setProductName(productName.trim());
}
if (StringUtil.hasLength(minSalePrice)) {
po.setMinSalePrice(new BigDecimal(minSalePrice));
}
if (StringUtil.hasLength(maxSalePrice)) {
po.setMaxSalePrice(new BigDecimal(maxSalePrice));
}
PageResult<Product> pageResult = productService.selectAll(po);
req.setAttribute("po", po);
req.setAttribute("pageResult", pageResult);
req.getRequestDispatcher("/page/product_list.jsp").forward(req, resp);
}
}

4.8、编写 product_list.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>商品列表</title>
<style>
a {
text-decoration: none;
}
</style>
<script type="text/javascript">
function checkDel(id) {
let flag = window.confirm("你确定要删除?");
if (flag) {
window.location.href = "/product?cmd=delete&id=" + id;
}
}
function changeCurrentPage(pageNum) {
// 改变当前页的值,修改要提交的 input 标签的值
document.getElementById("currentPage").value = pageNum;
// 提交第一个 form 表单,把输入框的当前页和页面条数提交给后台使用
document.forms[0].submit();
}
</script>
</head>
<body>
<div style="margin: auto; width: 800px;">
<h3 style="margin-top: 8%; margin-left: 50%"><span
style="font-weight: normal; font-size: 17px">用户名:</span>${USER_IN_SESSION.username}
<span style="font-weight: normal; font-size: 17px">&emsp;&emsp;头像:<a href="/page/change_img.jsp"> <img
src="${USER_IN_SESSION.headImg}" style="width: 60px"></a></span>
&emsp; <span><a href="/product?cmd=logout">注销</a></span></h3><br/> <button style="width: 56px; float: right; margin-right: 5%"><a href="/product?cmd=input"
style="font-size: 18px;">添加</a></button> <form action="/product" method="post">
商品名称:<input style="width: 80px" type="text" name="productName" value="${po.productName}"> &emsp;&emsp;
价格:<input style="width: 80px" type="number" name="minSalePrice" value="${po.minSalePrice}"> -
<input style="width: 80px" type="number" name="maxSalePrice" value="${po.maxSalePrice}">
&emsp;&emsp; <input type="button" onclick="changeCurrentPage(1)" value="提交"> <table border="1" cellspacing="0" cellpadding="0"
style="margin: auto; margin-top: 2%; border-color: lightskyblue; width: 80%">
<caption style="margin-bottom: 20px; font-size: larger">商品列表</caption>
<tr>
<th>ID</th>
<th>商品名称</th>
<th>目录</th>
<th>销售价</th>
<th>供应商</th>
<th>品牌</th>
<th>折扣</th>
<th>折扣价</th>
<th>操作</th>
</tr>
<c:forEach items="${pageResult.data}" var="product" varStatus="c">
<tr style="text-align: center">
<td>${c.count + (pageResult.currentPage - 1) * pageResult.pageSize}</td>
<td>${product.productName}</td>
<td>${product.dir_id}</td>
<td>${product.salePrice}</td>
<td>${product.supplier}</td>
<td>${product.brand}</td>
<td>${product.cutoff}</td>
<td>${product.costPrice}</td>
<td><a href="/product?cmd=input&id=${product.id}">修改</a> | <a href="#" onclick="checkDel(${product.id})">删除</a>
</td>
</tr>
</c:forEach>
<tr>
<td colspan="9">
<a href="#" onclick="changeCurrentPage(1)">首页</a>
<a href="#" onclick="changeCurrentPage(${pageResult.prevPage})">上一页</a>
<a href="#" onclick="changeCurrentPage(${pageResult.nextPage})">下一页</a>
<a href="#" onclick="changeCurrentPage(${pageResult.totalPage})">尾页</a>
当前 ${pageResult.currentPage}/${pageResult.totalPage} 页
一共${pageResult.totalCount}条数据
跳转到<input min="1" max="${pageResult.totalPage}" id="currentPage" type="number" name="currentPage" style="width: 40px"
onchange="changeCurrentPage(this.value)" value="${pageResult.currentPage}">页
每页<select name="pageSize" onchange="changeCurrentPage(1)">
<option value="3" ${pageResult.pageSize == 3? "selected" : ""}>3</option>
<option value="5" ${pageResult.pageSize == 5? "selected" : ""}>5</option>
<option value="8" ${pageResult.pageSize == 8? "selected" : ""}>8</option>
</select>条数据
</td>
</tr>
</table>
</form>
</div>
</body>
</html>

总结:

以上就是基于 mybatis 的分页和过滤查询了,代码仅供参考,欢迎讨论交流。

mybatis 实现分页和过滤模糊查询的更多相关文章

  1. 10 star组件之分页, search模糊查询, action批量处理

    1.分页组件高阶 1.分页的class形式(有bug,请看下面的) """ 自定义分页组件 """ class Pagination(obj ...

  2. 【MyBatis】多关键字的模糊查询

    目录 情景分析 题目 要求 相关代码 Mapper.java Impl.java mapper.xml test.java 思路分析 1.最开始,参数没有使用List,引起的问题 2.Mybatis的 ...

  3. 使用mybatis从mysql里进行模糊查询的编码问题

    关于这个问题,记录下我的解决方法,希望对有同样困惑的朋友,有所帮助. 问题描述: 我在做mybatis从mysql里模糊查询时,如果模糊的关键词是字母的话,可以查出来.如果模糊的关键词是汉字的话,查不 ...

  4. mybatis 特殊符号转义和模糊查询和批量插入

    1 xml文件特殊符号转义 <          < >          > <>   <> &      & &apos; ...

  5. mybatis中使用mysql的模糊查询字符串拼接(like)

    方法一: <!-- 根据hid,hanme,grade,模糊查询医院信息--> 方法一: List<Hospital> getHospitalLike(@Param(" ...

  6. MyBatis的手动映射与模糊查询

    一.手动映射 当实体类属性与数据库字段名不同时,无法自动映射,导致查询出空值,这时候可以使用手动映射 在select节点添加resultMap属性与resultMap节点建立关系

  7. 关于mybatis中sql映射文件模糊查询的使用

    1.从前台传递一个String类型的参数到后台进行查询,如果牵涉到模糊查询会报错,应该把参数封装到对象中再进行传递然后进行模糊查询 2.一个查询框,多个查询条件 <if test="c ...

  8. mybatis xml 文件中like模糊查询

    1.直接传参法 直接传参法,就是将要查询的关键字keyword,在代码中拼接好要查询的格式,如%keyword%,然后直接作为参数传入mapper.xml的映射文件中. 2.CONCAT()函数 My ...

  9. mybatis的动态sql及模糊查询

    1.动态sql 使用类似于jstl表达式来实现 2.模糊查找 用一个对象来封装条件 步骤: 1)新建一个条件实体 package com.hy.mybatis.entity; public class ...

随机推荐

  1. 面试官:Redis中哈希数据类型的内部实现方式是什么?

    面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:哈希数据类型的内 ...

  2. AutoResetEvent 与 ManualResetEvent

    实际上这两个东西是同一种东西,可以把他们理解为线程锁,两个不同的线程可以共享. 这两个类的构造函数参数都是传入一个 bool 值,这个 bool 值可以理解为一开始的时候,这个需要访问的资源是处于可用 ...

  3. laravel 7 xlsx 数据导入至 数据库

    网址: https://learnku.com/articles/32400 1:安装插件 环境要求 PHP: ^7.0 Laravel: ^5.5 安装方式 composer require maa ...

  4. 跨平台书签同步-Xmarks

    原文链接 Xmarks简介 Xmarks 是一款浏览器书签同步工具,它可以实现不同设备,不同浏览器之间的书签同步,并且是免费的. 有人会说,我们为什么需要一款专门的书签同步工具呢?Safari 自带的 ...

  5. XML与HTML的主要区别

    XML 与 HTML 的主要差异 XML 不是 HTML 的替代. XML 和 HTML 为不同的目的而设计: XML 被设计为传输和存储数据,其焦点是数据的内容. HTML 被设计用来显示数据,其焦 ...

  6. linux 常用命令:

    查看启动进程命令 ps -ef |  grep donet 1.vi 进入编辑界面 2.ls,ll 查看命令 3.cd 进入命令 4.i 进入插入界面 5. esc 退出编辑界面 6.输入:冒号,进入 ...

  7. ctf之Flask_fileUpload

    启动环境,显示如图: 直接f12产看源码信息: 大致意思是:使用python编写文件然后以图片格式上传系统会以ipython格式解析,就可获取flag. 编写python代码: import os o ...

  8. 学习廖雪峰的Git教程4--继续学习分支管理

    查看分支 git branch -a 查看远程分支 git branch 查看本地分支 创建分支 git checkout -b branch-name 在远程创建一个属于自己的分支 删除分支 删除本 ...

  9. TypeSciprt webpack配置

    初始化 初始化项目 npm init -y 安装依赖 npm install ... --save-dev 依赖包列表 名称 作用 webpack 构建工具webpack webpack-cli we ...

  10. Listener是什么?有什么作用?

    Listener是指Servlet中的监听器. Listener可以对ServletContext对象.HttpSession对象.ServletRequest对象进行监听.