学习内容:

分页设计


需求:使用 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. 矩池云助力科研算力免费上"云",让 AI 教学简单起来

    矩池云是一个专业的国内深度学习云平台,拥有着良好的深度学习云端训练体验,和高性价比的GPU集群资源.而且对同学们比较友好,会经常做一些大折扣的活动,最近双十一,全场所有的RTX 2070.Platin ...

  2. Spring Cloud Gateway 不小心换了个 Web 容器就不能用了,我 TM 人傻了

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

  3. 对SQL中游标的认识

    游标用于按顺序遍历结果集.但一般情况下,应尽量避免使用游标.原因: 1. 游标违背了关系模型,即按集合来考虑问题的思想: 2. 游标逐行对纪录进行操作,会带来额外的开销,使用游标的解决方案通常比使用集 ...

  4. laravel7 百度智能云检测图片是否合规

    APP 文件下建一个Libs目录建一个BaiduService文件,需要检测引入进行调用即可 BaiduService文件内容如下 <?php namespace App\Libs; use A ...

  5. BBS项目分布搭建五(评论相关功能实现)

    BBS项目分布搭建五(评论相关) 1. 根评论逻辑实现 # 在models.py文件中 修改: # 7. 评论表 parent = models.ForeignKey(to='self', null= ...

  6. Linux指令_入门基础

    一.基础指令语法 1.ls指令: 用法1:#ls 含义:列出当前工作目录下的所有文件/文件夹的名称. 用法2:#ls 路径 含义:列出指定路径下的所有文件/文件夹的名称 用法3:#ls 选项 路径 含 ...

  7. ybt1130:找第一个只出现一次的字符

    1130:找第一个只出现一次的字符 时间限制: 1000 ms         内存限制: 65536 KB提交数: 62333     通过数: 23786 [题目描述] 给定一个只包含小写字母的字 ...

  8. Intellij IDEA远程debug线上项目记录

    远程调试,特别是当你在本地开发的时候,你需要调试服务器上的程序时,远程调试就显得非常有用. JAVA 支持调试功能,本身提供了一个简单的调试工具JDB,支持设置断点及线程级的调试同时,不同的JVM通过 ...

  9. 张高兴的 Entity Framework Core 即学即用:(一)创建第一个 EF Core 应用

    写在前面 Entity Framework Core (EF Core) 是 .NET 平台流行的对象关系映射(ORM)框架.虽然 .NET 平台中 ORM 框架有很多,比如 Dapper.NHibe ...

  10. new和@Autowired的区别

    controller层: @RequestMapping("/payment") @RestController public class WxPayController { pu ...