学习内容:

分页设计


需求:使用 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. 学习linux(centos7)记录的笔记

    此随笔用于记录学习<linux鸟哥的私房菜>过程中1.遇到的问题及解决的过程 2.有必要记录的重要内容 3.对应书上操作的记录 开始于2021年6月18号 一个磁盘的分区通过格式化后成为一 ...

  2. MATLAB菜鸟入门笔记【作图章】

    1.函数标签[legend]         http://blog.csdn.net/wangcj625/article/details/6287735/

  3. [JS基础] 带你深入了解JS原型

    简介 下面这张图大家应该很很熟悉了,各位大佬讲原型及原型链的时候是大部分都会用到下面这张图片的 我想以自己的方式来讲述一遍,一是帮助我自己更好的复习,二是希望能够帮助到想要复习或者学习原型的同学 在讲 ...

  4. MyBatis报错—Type handler was null on parameter mapping for property 'createTime'. It was either not specified and/or could not be found for the javaType (javax.xml.crypto.Data) : jdbcType (null) combina

    原因是:在创建实体类的时候吧date类型写成data导致类型不匹配 Type handler was null on parameter mapping for property 'createTim ...

  5. Numpy库基础___二

    ndarray一个强大的N维数组对象Array •ndarray的变换 x.reshape(shape)重塑数组的shape,要求元素的个数一致,不改变原数组 x = np.ones((2,3,4), ...

  6. python3鸡兔同笼问题

    # 假设兔子有x只 for x in range(1,31): y = 30 - x if 4*x + 2*y == 90: print('兔子有%d只,鸡有%d只'%(x, y))

  7. 实践:Linux下安装mysql8.0

    镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 一.下载mysql8.0安装包 1.在local创建mysql文件夹 cd /usr/local mkdir mysql cd mysql 2.使 ...

  8. [FromBody]List<string> 用PostMan如何请求

    在MVC项目,写了一个API方法,如下: /// <summary>/// 测试/// </summary>/// <param name="idList&qu ...

  9. mybatis缓存-二级缓存

    1.2 二级缓存 [官方声明] => 如何开启[二级缓存] 默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存. 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行 ...

  10. Spring cloud config 客户端连接RabbitMQ 报 socket closed

    java.net.SocketException: socket closed at java.net.SocketInputStream.socketRead0(Native Method)     ...