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 {
@Autowired
private 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 {
@Autowired
private EmpMapper empMapper;
@Override
public 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 {
@Autowired
private EmpMapper empMapper;
@Override
public 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>