04-SpringBootWeb案例(下)

3. 员工管理

完成了部门管理的功能开发之后,我们进入到下一环节员工管理功能的开发。

基于以上原型,我们可以把员工管理功能分为:

  1. 分页查询(今天完成)
  2. 带条件的分页查询(今天完成)
  3. 删除员工(今天完成)
  4. 新增员工(后续完成)
  5. 修改员工(后续完成)

那下面我们就先从分页查询功能开始学习。

3.1 分页查询

3.1.1 基础分页

3.1.1.1 需求分析

我们之前做的查询功能,是将数据库中所有的数据查询出来并展示到页面上,试想如果数据库中的数据有很多(假设有十几万条)的时候,将数据全部展示出来肯定不现实,那如何解决这个问题呢?

使用分页解决这个问题。每次只展示一页的数据,比如:一页展示10条数据,如果还想看其他的数据,可以通过点击页码进行查询。

要想从数据库中进行分页查询,我们要使用 LIMIT 关键字,格式为:limit 开始索引 每页显示的条数

查询第1页数据的SQL语句是:
select * from emp limit 0,10;

查询第2页数据的SQL语句是:
select * from emp limit 10,10;

查询第3页的数据的SQL语句是:
select * from emp limit 20,10;

观察以上SQL语句,发现: 开始索引一直在改变 , 每页显示条数是固定的

开始索引的计算公式: 开始索引 = (当前页码 - 1) * 每页显示条数

我们继续基于页面原型,继续分析,得出以下结论:

  1. 前端在请求服务端时,传递的参数
    • 当前页码 page
    • 每页显示条数 pageSize
  2. 后端需要响应什么数据给前端
    • 所查询到的数据列表(存储到List 集合中)
    • 总记录数

后台给前端返回的数据包含:List集合(数据列表)、total(总记录数) 而这两部分我们通常封装到PageBean对象中,并将该对象转换为json格式的数据响应回给浏览器。

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {
	private Long total; //总记录数
	private List rows; //当前页数据列表
}
3.1.1.2 接口文档

员工列表查询

  • 基本信息

请求路径:/emps

请求方式:GET

接口描述:该接口用于员工列表数据的条件分页查询

  • 请求参数

参数格式:queryString

参数说明:

参数名 是否必须 示例 备注
name 姓名
gender 1 性别 , 1 男 , 2 女
begin 2010-01-01 范围匹配的开始时间(入职日期)
end 2020-01-01 范围匹配的结束时间(入职日期)
page 1 分页查询的页码,如果未指定,默认为1
pageSize 10 分页查询的每页记录数,如果未指定,默认为10

请求数据样例:

复制代码
/emps?name=张&gender=1&begin=2007-09-01&end=2022-09-01&page=1&pageSize=10
  • 响应数据

参数格式:application/json

参数说明:

参数名 类型 是否必须 默认值 备注 其他信息
code number 必须 响应码,1 代表成功,0 代表失败
msg string 非必须 提示信息
data object[ ] 非必须 返回的数据
l- total number 必须 总记录数
l- rows object[] 必须 id item 类型:object
l- id number 非必须 id
l- username string 非必须 用户名
l- name string 非必须 姓名
l- password string 非必须 密码
l- entrydate string 非必须 入职日期
l- gender number 非必须 性别,1 男 2女
l- image string 非必须 职位, 说明: 1 班主任,2 讲师,3 学工主管, 4 教研主管, 5 咨询师
l- job number 非必须 图像
l- deptId number 非必须 部门id
l- createTime string 非必须 创建时间
l- updateTime string 非必须 更新时间

响应数据样例:

json 复制代码
{
	"code": 1,
	"msg": "success",
	"data": {
	"total": 2,
	"rows": [
 		{
			"id": 1,
			"username": "jinyong",
			"password": "123456",
			"name": "金庸",
			"gender": 1,
			"image": "https://web-framework.oss-cnhangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg",
			"job": 2,
			"entrydate": "2015-01-01",
			"deptId": 2,
			"createTime": "2022-09-01T23:06:30",
			"updateTime": "2022-09-02T00:29:04"
 		},
 		{
			"id": 2,
			"username": "zhangwuji",
			"password": "123456",
			"name": "张无忌",
			"gender": 1,
			"image": "https://web-framework.oss-cnhangzhou.aliyuncs.com/2022-09-02-00-27-53B.jpg",
			"job": 2,
			"entrydate": "2015-01-01",
			"deptId": 2,
			"createTime": "2022-09-01T23:06:30",
			"updateTime": "2022-09-02T00:29:04"
 		}
 		]
 	}
}
3.1.1.3 思路分析

分页查询需要的数据,封装在PageBean对象中:

3.1.1.4 功能开发

通过查看接口文档:员工列表查询

请求路径:/emps

请求方式:GET

请求参数:跟随在请求路径后的参数字符串。 例:/emps?page=1&pageSize=10

响应数据:json格式

EmpController

java 复制代码
package com.itheima.controller;

import com.itheima.pojo.PageBean;
import com.itheima.pojo.Result;
import com.itheima.service.EmpService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
@CrossOrigin(origins = "*", maxAge = 3600)
public class EmpController {
    @Autowired
    private EmpService empService;

    // 条件分页查询
    @GetMapping("/emps")
    public Result page(@RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer pageSize) {
        // 记录日志
        log.info("分页查询,参数:{},{}", page, pageSize);
        // 调用业务层分页查询功能
        PageBean pageBean = empService.page(page, pageSize);
        // 响应
        return Result.success(pageBean);
    }
}

@RequestParam(defaultValue="默认值") //设置请求参数默认值

EmpService

java 复制代码
package com.itheima.service;

import com.itheima.pojo.PageBean;
import org.springframework.stereotype.Service;

@Service
public interface EmpService {
    /**
     * 条件分页查询
     *
     * @param page     页码
     * @param pageSize 每页展示记录数
     * @return
     */

    PageBean page(Integer page, Integer pageSize);
}

EmpServiceImpl

java 复制代码
package com.itheima.service.impl;

import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.PageBean;
import com.itheima.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmpServiceImpl implements EmpService {
    @Autowired
    private EmpMapper empMapper;

    @Override
    public PageBean page(Integer page, Integer pageSize) {
        // 1、获取总记录数
        long count = empMapper.count();
        // 2、获取分页查询结果列表
        Integer start = (page - 1) * pageSize;  // 计算起始索引 , 公式:(页码-1)*页大小
        List<Emp> empList = empMapper.page(start, pageSize);
        // 3、封装PageBean对象
        PageBean pageBean = new PageBean(count, empList);
        return pageBean;
    }
}

EmpMapper

java 复制代码
package com.itheima.mapper;

import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface EmpMapper {
    /**
     * 获取总记录数
     *
     * @return
     */
    @Select("select count(*) from emp")
    public long count();

    /**
     * 获取当前页的结果列表
     *
     * @param start
     * @param pageSize
     * @return
     */
    @Select("select * from emp limit #{start},#{pageSize}")
    public List<Emp> page(Integer start, Integer pageSize);
}
3.1.1.5 功能测试

功能开发完成后,重新启动项目,使用postman,发起POST请求:

3.1.1.6 前后端联调

打开浏览器,测试后端功能接口:

3.1.2 分页插件

3.1.2.1 介绍

前面我们已经完了基础的分页查询,大家会发现:分页查询功能编写起来比较繁琐。

在Mapper接口中定义两个方法执行两条不同的SQL语句:

  1. 查询总记录数
  2. 指定页码的数据列表
    在Service当中,调用Mapper接口的两个方法,分别获取:总记录数、查询结果列表,然后在将 获?>取的数据结果封装到PageBean对象中。 大家思考下:在未来开发其他项目,只要涉及到分页查询 >功能(例:订单、用户、支付、商品),

都必须按照以上操作完成功能开发

结论:原始方式的分页查询,存在着"步骤固定"、"代码频繁"的问题

解决方案:可以使用一些现成的分页插件完成。对于Mybatis来讲现在最主流的就是PageHelper。

PageHelper是Mybatis的一款功能强大、方便易用的分页插件,支持任何形式的单标、多表的

分页查询。

官网:https://pagehelper.github.io/

在执行empMapper.list()方法时,就是执行:select * from emp 语句,怎么能够实现分页操作呢?

分页插件帮我们完成了以下操作:

  1. 先获取到要执行的SQL语句:select * from emp
  2. 把SQL语句中的字段列表,变为:count(*)
  3. 执行SQL语句:select count(*) from emp //获取到总记录数
  4. 再对要执行的SQL语句:select * from emp 进行改造,在末尾添加 limit ? ,?
  5. 执行改造后的SQL语句:select * from emp limit ? , ?
3.1.2.2 代码实现

当使用了PageHelper分页插件进行分页,就无需再Mapper中进行手动分页了。 在Mapper中我们只

需要进行正常的列表查询即可。在Service层中,调用Mapper的方法之前设置分页参数,在调用

Mapper方法执行查询之后,解析分页结果,并将结果封装到PageBean对象中返回。

1、在pom.xml引入依赖

复制代码
<dependency>
	<groupId>com.github.pagehelper</groupId>
	<artifactId>pagehelper-spring-boot-starter</artifactId>
	<version>1.4.2</version>
</dependency>

2、EmpMapper

java 复制代码
@Mapper
public interface EmpMapper {
	//获取当前页的结果列表
	@Select("select * from emp")
	public List<Emp> page(Integer start, Integer pageSize);
}

3、EmpServiceImpl

java 复制代码
@Override
public PageBean page(Integer page, Integer pageSize) {
	// 设置分页参数
	PageHelper.startPage(page, pageSize);
	// 执行分页查询
	List<Emp> empList = empMapper.list(name,gender,begin,end);
	// 获取分页结果
	Page<Emp> p = (Page<Emp>) empList;
	//封装PageBean
	PageBean pageBean = new PageBean(p.getTotal(), p.getResult());
	return pageBean;
}
3.1.2.3 测试

功能开发完成后,我们重启项目工程,打开postman,发起GET请求,访问 :http://localhost:8080/emps?page=1&pageSize=5

后端程序SQL输出:

3.1.2.4 小结

3.2 分页查询(带条件)

完了分页查询后,下面我们需要在分页查询的基础上,添加条件。

3.2.1 需求

通过员工管理的页面原型我们可以看到,员工列表页面的查询,不仅仅需要考虑分页,还需要考虑查询条件。 分页查询我们已经实现了,接下来,我们需要考虑在分页查询的基础上,再加上查询条件。

我们看到页面原型及需求中描述,搜索栏的搜索条件有三个,分别是:

  • 姓名:模糊匹配
  • 性别:精确匹配
  • 入职日期:范围匹配
sql 复制代码
select *
from emp
where
   name like concat('%','张','%') -- 条件1:根据姓名模糊匹配
   and gender = 1 -- 条件2:根据性别精确匹配
   and entrydate = between '2000-01-01' and '2010-01-01' -- 条件3:根据入职日期范围匹配
order by update_time desc;

而且上述的三个条件,都是可以传递,也可以不传递的,也就是动态的。 我们需要使用前面学习的

Mybatis中的动态SQL 。

3.2.2 思路分析

3.2.3 功能开发

通过查看接口文档:员工列表查询

请求路径:/emps

请求方式:GET

请求参数:

参数名 是否必须 示例 备注
name 姓名
gender 1 性别 , 1 男 , 2 女
begin 2010-01-01 范围匹配的开始时间(入职日期)
end 2020-01-01 范围匹配的结束时间(入职日期)
page 1 分页查询的页码,如果未指定,默认为1
pageSize 10 分页查询的每页记录数,如果未指定,默认为10

在原有分页查询的代码基础上进行改造:
EmpController

java 复制代码

EmpService

java 复制代码

EmpServiceImpl

java 复制代码

EmpMapper

java 复制代码

EmpMapper.xml

xml 复制代码
相关推荐
莫寒清5 天前
Mybatis的插件原理
面试·mybatis
莫寒清5 天前
MyBatis 中动态 SQL 的作用
面试·mybatis
吹晚风吧5 天前
实现一个mybatis插件,方便在开发中清楚的看出sql的执行及执行耗时
java·sql·mybatis
码云数智-大飞5 天前
像写 SQL 一样搜索:dbVisitor 如何用 MyBatis 范式颠覆 ElasticSearch 开发
sql·elasticsearch·mybatis
Mr__Miss6 天前
mybatisPlus分页组件3.5.15版本报错解决方案
mybatis
无名-CODING6 天前
MyBatis中#{}和${}完全指南:从原理到实战
mybatis
鹿角片ljp6 天前
短信登录:基于 Session 实现(黑马点评实战)
java·服务器·spring boot·mybatis
莫寒清6 天前
MyBatis 如何防止 SQL 注入?
面试·mybatis
玄〤6 天前
个人博客网站搭建day5--MyBatis-Plus核心配置与自动填充机制详解(漫画解析)
java·后端·spring·mybatis·springboot·mybatis plus
计算机学姐6 天前
基于SpringBoot的服装购物商城销售系统【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·mysql·信息可视化·mybatis·推荐算法