学习内容:

分页设计


需求:使用 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. 【Apollo自动驾驶源码解读】车道线的感知和高精地图融合

    模式选择 在modules/map/relative_map/conf/relative_map_config.pb.txt文件中对模式进行修改: lane_source: OFFLINE_GENER ...

  2. laravel7文件上传至七牛云并保存在本地图片

    HTML代码: <form class="layui-form" action="{{route('doctor.store')}}" method=&q ...

  3. tp5用户id登录进行权限设置

    HTML代码:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  4. php 23种设计模型 - 装饰模式

    装饰器模式(Decorator) 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. ...

  5. Jira8.0.2安装及破解

    最近开发部总监需要部署JIRA管理项目,就安装了一个JIRA8.5.7版安装并破解后,有天断电重启了,发现启动不了提示连接不上数据库.后来我又换了台机器重新安装后又进行了重启发现此破解版本存在问题.并 ...

  6. 打靶笔记-01-vulnhub-moneybox

    打靶笔记-01-vulnhub-moneybox 本篇笔记根据苑老师视频进行学习记录 https://www.bilibili.com/video/BV1Lv411n7Lq/?spm_id_from= ...

  7. Python入门随记(3)

    1.len() 长度或规模函数 2.Unicode转为单字符用chr() 单字符转为Unicode用ord() 3.关于字符的操作函数 函数 作用 lower() 变为小写 upper() 变为大写 ...

  8. .NET6: 开发基于WPF的摩登三维工业软件 (10) - 机器人

    基于前文介绍的Ribbon界面.插件化.MVVM模式等内容,我们搭建了一个软件雏形.本文将综合之前的内容在RapidCAX框架中集成Robot组件,实现一个简单的机器人正向模拟模块. 1 目标 基于M ...

  9. RENIX 软件RAW流发送——网络测试仪实操

    本文主要介绍了RENIX软件如何进行RAW流发送操作.文章通过预约端口.添加RAW流.修改负载.发送流量.查看流统计.数据包捕获六个步骤详细介绍了操作过程. 步骤一:预约端口.1.先安装RENIX软件 ...

  10. Java基础——方法重写

    什么是方法重写? 子类中出现和父类中完全一样的方法声明 什么时候可以进行方法重写? 在子类需要父类的功能的同时,功能主体子类有自己的特有内容时,可以重写,一面沿袭了父类的功能一面又定义了子类特有的内容 ...