mybatis 实现分页和过滤模糊查询
基于 mybatis 的分页和过滤查询
学习内容:
分页设计
需求:使用 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 >= #{minSalePrice}
</if>
<if test="maxSalePrice != null">
and salePrice <= #{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">  头像:<a href="/page/change_img.jsp"> <img
src="${USER_IN_SESSION.headImg}" style="width: 60px"></a></span>
  <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}">   
价格:<input style="width: 80px" type="number" name="minSalePrice" value="${po.minSalePrice}"> -
<input style="width: 80px" type="number" name="maxSalePrice" value="${po.maxSalePrice}">
   <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 实现分页和过滤模糊查询的更多相关文章
- 10 star组件之分页, search模糊查询, action批量处理
1.分页组件高阶 1.分页的class形式(有bug,请看下面的) """ 自定义分页组件 """ class Pagination(obj ...
- 【MyBatis】多关键字的模糊查询
目录 情景分析 题目 要求 相关代码 Mapper.java Impl.java mapper.xml test.java 思路分析 1.最开始,参数没有使用List,引起的问题 2.Mybatis的 ...
- 使用mybatis从mysql里进行模糊查询的编码问题
关于这个问题,记录下我的解决方法,希望对有同样困惑的朋友,有所帮助. 问题描述: 我在做mybatis从mysql里模糊查询时,如果模糊的关键词是字母的话,可以查出来.如果模糊的关键词是汉字的话,查不 ...
- mybatis 特殊符号转义和模糊查询和批量插入
1 xml文件特殊符号转义 < < > > <> <> & & ' ...
- mybatis中使用mysql的模糊查询字符串拼接(like)
方法一: <!-- 根据hid,hanme,grade,模糊查询医院信息--> 方法一: List<Hospital> getHospitalLike(@Param(" ...
- MyBatis的手动映射与模糊查询
一.手动映射 当实体类属性与数据库字段名不同时,无法自动映射,导致查询出空值,这时候可以使用手动映射 在select节点添加resultMap属性与resultMap节点建立关系
- 关于mybatis中sql映射文件模糊查询的使用
1.从前台传递一个String类型的参数到后台进行查询,如果牵涉到模糊查询会报错,应该把参数封装到对象中再进行传递然后进行模糊查询 2.一个查询框,多个查询条件 <if test="c ...
- mybatis xml 文件中like模糊查询
1.直接传参法 直接传参法,就是将要查询的关键字keyword,在代码中拼接好要查询的格式,如%keyword%,然后直接作为参数传入mapper.xml的映射文件中. 2.CONCAT()函数 My ...
- mybatis的动态sql及模糊查询
1.动态sql 使用类似于jstl表达式来实现 2.模糊查找 用一个对象来封装条件 步骤: 1)新建一个条件实体 package com.hy.mybatis.entity; public class ...
随机推荐
- 面试官:Redis中哈希数据类型的内部实现方式是什么?
面试官:Redis中基本的数据类型有哪些? 我:Redis的基本数据类型有:字符串(string).哈希(hash).列表(list).集合(set).有序集合(zset). 面试官:哈希数据类型的内 ...
- AutoResetEvent 与 ManualResetEvent
实际上这两个东西是同一种东西,可以把他们理解为线程锁,两个不同的线程可以共享. 这两个类的构造函数参数都是传入一个 bool 值,这个 bool 值可以理解为一开始的时候,这个需要访问的资源是处于可用 ...
- laravel 7 xlsx 数据导入至 数据库
网址: https://learnku.com/articles/32400 1:安装插件 环境要求 PHP: ^7.0 Laravel: ^5.5 安装方式 composer require maa ...
- 跨平台书签同步-Xmarks
原文链接 Xmarks简介 Xmarks 是一款浏览器书签同步工具,它可以实现不同设备,不同浏览器之间的书签同步,并且是免费的. 有人会说,我们为什么需要一款专门的书签同步工具呢?Safari 自带的 ...
- XML与HTML的主要区别
XML 与 HTML 的主要差异 XML 不是 HTML 的替代. XML 和 HTML 为不同的目的而设计: XML 被设计为传输和存储数据,其焦点是数据的内容. HTML 被设计用来显示数据,其焦 ...
- linux 常用命令:
查看启动进程命令 ps -ef | grep donet 1.vi 进入编辑界面 2.ls,ll 查看命令 3.cd 进入命令 4.i 进入插入界面 5. esc 退出编辑界面 6.输入:冒号,进入 ...
- ctf之Flask_fileUpload
启动环境,显示如图: 直接f12产看源码信息: 大致意思是:使用python编写文件然后以图片格式上传系统会以ipython格式解析,就可获取flag. 编写python代码: import os o ...
- 学习廖雪峰的Git教程4--继续学习分支管理
查看分支 git branch -a 查看远程分支 git branch 查看本地分支 创建分支 git checkout -b branch-name 在远程创建一个属于自己的分支 删除分支 删除本 ...
- TypeSciprt webpack配置
初始化 初始化项目 npm init -y 安装依赖 npm install ... --save-dev 依赖包列表 名称 作用 webpack 构建工具webpack webpack-cli we ...
- Listener是什么?有什么作用?
Listener是指Servlet中的监听器. Listener可以对ServletContext对象.HttpSession对象.ServletRequest对象进行监听.