SpringBoot员工分页查询

需求分析与设计

一:产品原型

系统中的员工很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。而在我们的分页查询页面中, 除了分页条件以外,还有一个查询条件 "员工姓名"。

查询员工原型:

业务规则

  • 根据页码展示员工信息

  • 每页展示10条数据

  • 分页查询时可以根据需要(非必须——>动态SQL),输入员工姓名进行查询

 二:接口设计

查询——>get

三个参数——>员工姓名(非必须)、页码、每页记录数

找到资料-->项目接口文档-->苍穹外卖-管理端接口.html

 

 细节:

  • 请求参数是Query类型,无需@RequestBody,不是json格式提交,在路径后直接拼接。/admin/employee/page?name=zhangsan
  • total:总记录数

  • records[]:当前这一页需要展示的数据集合

  • 返回数据中records数组中使用Employee实体类对属性进行封装。

代码开发

一:设计DTO类

将前端的请求参数封装成DTO对象,在sky-pojo模块中:

package com.sky.dto;

import lombok.Data;

import java.io.Serializable;

@Data
public class EmployeePageQueryDTO implements Serializable {

    //员工姓名
    private String name;

    //页码
    private int page;

    //每页显示记录数
    private int pageSize;

}

二:封装PageResult(分页查询重点)

后面所有的分页查询,统一都封装为PageResult对象。

在sky-common模块的result包下(包中定义返回类)

package com.sky.result;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

/**
 * 封装分页查询结果
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult implements Serializable {

    private long total; //总记录数

    private List records; //当前页数据集合

}

还需要后端统一返回结果:员工信息分页查询后端返回的对象类型为: Result<PageResult>

三:Controller类

	/**
     * 员工分页查询
     * @param employeePageQueryDTO
     * @return
     */
    @GetMapping("/page")
    @ApiOperation("员工分页查询")
    public Result<PageResult> page(EmployeePageQueryDTO employeePageQueryDTO){
        log.info("员工分页查询,参数为:{}", employeePageQueryDTO);
        PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);//后续定义
        return Result.success(pageResult);
    }

 四:Service类

	/**
     * 分页查询
     *
     * @param employeePageQueryDTO
     * @return
     */
    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO) {
        // select * from employee limit 0,10
        //开始分页查询
        PageHelper.startPage(employeePageQueryDTO.getPage(), employeePageQueryDTO.getPageSize());

        Page<Employee> page = employeeMapper.pageQuery(employeePageQueryDTO);//后续定义

        long total = page.getTotal();
        List<Employee> records = page.getResult();

        return new PageResult(total, records);
    }

注意:

<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper-spring-boot-starter</artifactId>
   <version>${pagehelper}</version>
</dependency>

此处使用 mybatis 的分页插件 PageHelper 来简化分页代码的开发,调用startPage方法告诉Page对象当前页码以及一页多少记录。

Page对象是该插件提供的,调用pageQuery方法自动的进行分页操作。

mapper层只需要正常的进行查询即可,无需考虑分页。

故在pom.xml文中添加依赖

<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper-spring-boot-starter</artifactId>
   <version>${pagehelper}</version>
</dependency>

五:Mapper层

	/**
     * 分页查询
     * @param employeePageQueryDTO
     * @return
     */
    Page<Employee> pageQuery(EmployeePageQueryDTO employeePageQueryDTO);

利用alt+enter点击create statements快速在对应的XML文件快速生成select动态sql语句:

<select id="pageQuery" resultType="com.sky.entity.Employee">
        select * from employee
        <where>
            <if test="name != null and name != ''">
                and name like concat('%',#{name},'%')
            </if>
        </where>
        order by create_time desc
    </select>

功能测试

 代码完善

问题描述:操作时间字段显示有问题。

服务端返回给前端的是数组类型。 

解决方式:

1). 方式一

在属性上加上注解,对日期进行格式化

解决方式:

1). 方式一

在属性上加上注解,对日期进行格式化

解决方式:

1). 方式一

在属性上加上注解,对日期进行格式化

但这种方式,需要在每个时间属性上都要加上该注解,使用较麻烦,不能全局处理。

2). 方式二(推荐 )

在WebMvcConfiguration中扩展SpringMVC的消息转换器,统一对日期类型进行格式处理

	/**
     * 扩展Spring MVC框架的消息转化器
     * @param converters
     */
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展消息转换器...");
        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器,对象转换器可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转化器加入容器中
        converters.add(0,converter);
    }

 添加后,再次测试

时间格式定义,sky-common模块中

package com.sky.json;

public class JacksonObjectMapper extends ObjectMapper {

	//.......
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
    //.......

    }
}

注意:

/**
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
 */

<think>嗯,用户想了解如何在Spring Boot和MyBatis中实现员工管理的分页查询。首先,我需要确定用户的需求是什么。可能用户正在开发一个员工管理系统,需要处理大量数据,因此分页是必要的功能。分页可以提升性能,避免一次性加载过多数据,同时改善用户体验。 接下来,我需要回忆Spring Boot和MyBatis整合分页的常见方法。通常有两种方式:使用MyBatis的内部分页机制,或者结合PageHelper这样的第三方插件。PageHelper比较方便,因为它可以自动拦截查询并添加分页逻辑,而无需手动编写LIMIT和OFFSET。 然后,用户可能对具体步骤不太清楚,所以需要分步骤讲解。首先,项目配置,添加必要的依赖,比如MyBatis Spring Boot Starter和PageHelper。然后,配置分页插件,确保PageHelper在MyBatis中生效。 接着是代码部分,需要创建实体类Employee,Mapper接口,以及对应的XML映射文件。在Mapper中定义查询方法,比如selectAllEmployees,并在XML中编写SQL,这里不需要手动写分页参数,因为PageHelper会自动处理。 然后是Service层,调用PageHelper的startPage方法,传入页码和每页数量,之后执行查询,PageInfo会封装分页结果,包括总记录数、当前页、每页数量等信息。 Controller层负责接收请求参数,调用Service方法,返回分页数据。可能需要处理前端传递的页码和每页大小的参数,设置默认值,避免无效输入。 用户可能遇到的问题包括依赖冲突、PageHelper配置错误、SQL语句没有正确分页等。需要提醒注意事项,比如PageHelper必须在查询方法前调用,否则分页不生效。此外,参数传递是否正确,返回的数据结构是否包含必要的信息如总页数、当前页等。 另外,用户可能想知道如何测试分页功能,可以使用Postman或者Swagger发送请求,检查返回的数据是否符合预期,包括数据列表和分页信息是否正确。 最后,可能需要对比其他分页方式,比如使用MyBatis-Plus的内置分页功能,但用户的问题明确提到MyBatis,所以还是以PageHelper为主。总结步骤,确保用户能一步步跟随实现,同时提供代码示例和配置说明,帮助用户实际应用。</think>以下是使用Spring Boot + MyBatis实现员工管理分页查询的详细步骤说明: --- ### 一、实现原理 分页实现的核心要素: 1. **前端参数**:当前页码(pageNum)、每页条数(pageSize) 2. **数据库支持**:使用SQL的`LIMIT`和`OFFSET`语句 3. **后端封装**:返回包含数据列表和分页信息的对象 --- ### 二、具体实现步骤 #### 1. 添加依赖(pom.xml) ```xml <!-- MyBatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <!-- PageHelper分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.6</version> </dependency> ``` #### 2. 配置分页插件(application.yml) ```yaml pagehelper: helper-dialect: mysql # 数据库类型 reasonable: true # 分页合理化 support-methods-arguments: true ``` #### 3. 创建员工实体类 ```java @Data public class Employee { private Long id; private String name; private Integer age; private String department; private LocalDateTime createTime; } ``` #### 4. Mapper接口定义 ```java @Mapper public interface EmployeeMapper { List<Employee> selectAllEmployees(); } ``` #### 5. XML映射文件(EmployeeMapper.xml) ```xml <select id="selectAllEmployees" resultType="com.example.entity.Employee"> SELECT * FROM employee ORDER BY create_time DESC </select> ``` #### 6. Service层实现 ```java @Service @RequiredArgsConstructor public class EmployeeService { private final EmployeeMapper employeeMapper; public PageInfo<Employee> getEmployees(int pageNum, int pageSize) { PageHelper.startPage(pageNum, pageSize); List<Employee> employees = employeeMapper.selectAllEmployees(); return new PageInfo<>(employees); } } ``` #### 7. Controller层 ```java @RestController @RequestMapping("/employees") @RequiredArgsConstructor public class EmployeeController { private final EmployeeService employeeService; @GetMapping public Result<PageInfo<Employee>> listEmployees( @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) { return Result.success(employeeService.getEmployees(pageNum, pageSize)); } } ``` #### 8. 统一返回结果封装 ```java @Data @NoArgsConstructor @AllArgsConstructor public class Result<T> { private Integer code; private String msg; private T data; public static <T> Result<T> success(T data) { return new Result<>(200, "success", data); } } ``` --- ### 三、分页结果示例 ```json { "code": 200, "msg": "success", "data": { "total": 100, // 总记录数 "pageNum": 1, // 当前页码 "pageSize": 10, // 每页数量 "pages": 10, // 总页数 "list": [/* 员工数据数组 */] } } ``` --- ### 四、关键点说明 1. **PageHelper原理**: - 通过AOP拦截Mapper方法调用 - 自动在SQL后追加`LIMIT ?, ?` - 执行两次SQL(先查总数,再查分页数据) 2. **分页参数传递**: ```http GET /employees?pageNum=2&pageSize=20 ``` 3. **前端分页控件对接**: - 需要总记录数(total) - 需要总页数(pages) - 当前页码(pageNum)和每页数量(pageSize) --- ### 五、扩展优化建议 1. **条件分页查询**: ```java PageHelper.startPage(pageNum, pageSize); employeeMapper.selectByCondition(condition); ``` 2. **自定义排序**: ```http GET /employees?sortField=createTime&sortOrder=desc ``` 3. **性能优化**: - 避免`SELECT *`,明确指定字段 - 对常用查询字段添加索引 4. **安全防护**: ```java // 限制最大每页数量 pageSize = Math.min(pageSize, 100); ``` --- ### 六、常见问题排查 1. **分页不生效**: - 检查是否在Mapper方法调用前执行`PageHelper.startPage()` - 确认SQL方言配置正确 2. **总数统计错误**: - 避免在分页查询中使用`GROUP BY` - 检查是否存在嵌套查询 3. **内存溢出风险**: - 禁止无条件全表分页查询 - 添加合理的查询条件限制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值