SpringBoot学习记录(四)之分页查询
- 一、业务需求
- 1、基本信息
- 2、请求参数
- 3、相应数据
- 二、传统方式分页
- 三、使用PageHelper分页插件
一、业务需求
根据条件进行员工数据的条件分页查询
1、基本信息
请求路径: /emps
请求方式: GET
接口描述: 该接口用于员工列表数据的条件分页查询
2、请求参数
参数格式:queryString
参数说明:
请求数据样例:
/emps?name=张&gender=1&begin=2007-09-01&end=2022-09-01&page=1&pageSize=10
3、相应数据
参数格式:application/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"}]}}
二、传统方式分页
在SQL语句中直接使用limit进行分页。
由于要返回一个结果列表(List)和总记录数(int \ long),所以需要额外添加一个PageBean实体类来接收返回的结果。
pojo.PageBean
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageBean {public long total; //总记录数public List rows; //结果列表
}
EmpController
@RestController
public class EmpController {@Autowiredprivate EmpService empService;// 员工列表数据的条件分页查询 请求数据样例: emps?name=张&gender=1&begin=2007-09-01&end=2022-09-01&page=1&pageSize=10@GetMapping("/emps")public Result getEmps(@RequestParam(required = false) String name,@RequestParam(required = false) Short gender,@DateTimeFormat(pattern ="yyyy-MM-dd") LocalDate begin,@DateTimeFormat(pattern ="yyyy-MM-dd") LocalDate end,@RequestParam(defaultValue = "1") Integer page, //页码@RequestParam(defaultValue = "10") Integer pageSize) //每页记录数
{// PageBean实体类接收查询到的数据和总数据条数PageBean emps = empService.getEmps(name, gender, begin, end, page, pageSize);if(emps.getTotal() == 0){return Result.error("查询失败");}else {return Result.success(emps);}}
}
分页的重点在service层
EmpService
@Service
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic PageBean getEmps(String name, Short gender, LocalDate begin, LocalDate end, Integer page, Integer pageSize) {// start是sql语句中limit条件的第一个参数,表示第几条记录 int start = (page-1)*pageSize; // mapper中定义了两个sql,第一个是gerEmps,用来条件查询数据List<Emp> list = empMapper.getEmps(name, gender, begin, end,start,pageSize);// mapper中第二个sql,getTotalEmp,用来查询总记录数量。long total = empMapper.getTotalEmp();// 使用有参构造,将两个结果封装PageBean emps = new PageBean(total,list);return emps;}
}
EmpMapper
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--分页获取员工数据--><select id="getEmps" resultType="Emp">select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp<where><if test="name != null and name !='' " >name like concat('%',#{name},'%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null" >and entrydate between #{begin} and #{end}</if> </where>limit #{start},#{pageSize}</select><!-- 使用count(*) 获取总记录数--><select id="getTotalEmp" resultType="long">select count(*) from emp</select>
</mapper>
三、使用PageHelper分页插件
准备工作
导入依赖:
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.7</version>
</dependency>
注意版本问题,我用的springboot版本为 3.x,所以对应的pagehelper要使用1.4.7及以上的版本。
最开始的时候我使用的是1.4.2版本,分页并未生效。
PageBean和controller层并未修改,不再额外展示。
EmpService
public class EmpServiceImpl implements EmpService {@Autowiredprivate EmpMapper empMapper;@Overridepublic PageBean getEmps(String name, Short gender, LocalDate begin, LocalDate end, Integer page, Integer pageSize) {// 在进行数据库查询前启动分页,PageHelper.startPage( 想要查询的页码, 每页几条记录 );PageHelper.startPage(page, pageSize);// mapper查询到数据List<Emp> emps = empMapper.getEmps(name, gender, begin, end, page, pageSize);//把查询结果强转为Page类型 下面会介绍第二种形式Page<Emp> p = (Page<Emp>) emps;//Page中封装很多我们需要的信息,如getTotal是总记录数,getResult是分页之后的结果。//创建PageBean对象并将信息封装 并返回PageBean pageBean = new PageBean(p.getTotal(),p.getResult());return pageBean;}}
//把查询结果强转为Page类型Page<Emp> p = (Page<Emp>) emps;
这是其中的第一种方法,把查询的信息强转为Page,但还有另外一种方法。
// 将查询到的数据封装到PageInfo对象中。PageInfo<Emp> p = new PageInfo<Emp>(emps);// 这种情况下,获取分页结果是 p.getList() 而不是 p.getResult()List<Emp> list= p.getList();
PageInfo中的其他信息
pageNum:当前页的页码
pageSize:每页显示的条数
size:当前页显示的真实条数
total:总记录数
pages:总页数
prePage:上一页的页码
nextPage:下一页的页码
isFirstPage/isLastPage:是否为第一页/最后一页
hasPreviousPage/hasNextPage:是否存在上一页/下一页
navigatePages:导航分页的页码数
navigatepageNums:导航分页的页码,[4, 5, 6, 7, 8]
EmpMapper
使用分页插件的mapper只需要按条件查询数据即可,并且不需要为mapper传递limit的参数。
插件会自动为sql语句后拼接 limit。
<!--分页获取员工数据--><select id="getEmps" resultType="Emp">select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp<where><if test="name != null and name !='' " >name like concat('%',#{name},'%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null" >and entrydate between #{begin} and #{end}</if></where></select>