小工具知识网

当前位置: 首页 > 行业知识 > 【SpringBoot篇】分页查询 | 扩展SpringMvc的消息转换器

行业知识

【SpringBoot篇】分页查询 | 扩展SpringMvc的消息转换器

2026-11-08 07:06:43 来源:互联网转载

文章目录

  • 什么是分页查询
  • 代码实现
    • ⭐问题
    • 解决方法

      做了几个项目,发现在这几个项目里面,都实现了分页查询效果,所以就总结一下,方便学习

      我们基于黑马程序员的苍穹外卖来讲解分页查询的要点

      什么是分页查询

      分页查询是指将大量数据按照固定大小的页进行切分,每次查询只返回一页数据,通过不断翻页来获取全部数据。

      代码实现

      Result.java

      这是一个common类,好多方法都可以使用

      package com.sky.result;import lombok.Data;import java.io.Serializable;/** * 后端统一返回结果 * @param  */@Datapublic class Result implements Serializable {    private Integer code; //编码:1成功,0和其它数字为失败    private String msg; //错误信息    private T data; //数据    public static  Result success() {        Result result = new Result();        result.code = 1;        return result;    }    public static  Result success(T object) {        Result result = new Result();        result.data = object;        result.code = 1;        return result;    }    public static  Result error(String msg) {        Result result = new Result();        result.msg = msg;        result.code = 0;        return result;    }}

      所有的分页查询,我们都统一封装为PageResult对象,来表示分页查询结果

      PageResult.java

      package com.sky.result;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.io.Serializable;import java.util.List;/** * 封装分页查询结果 */@Data@AllArgsConstructor@NoArgsConstructorpublic class PageResult implements Serializable {    private long total; //总记录数    private List records; //当前页数据集合}

      EmployeeController.java

      我们查看接口文档,发现接口路径是GET方式,并且请求参数是query,不是json,那么就不需要使用注解@ResponseBody了

      package com.sky.controller.admin;import com.sky.constant.JwtClaimsConstant;import com.sky.dto.EmployeeDTO;import com.sky.dto.EmployeeLoginDTO;import com.sky.dto.EmployeePageQueryDTO;import com.sky.entity.Employee;import com.sky.properties.JwtProperties;import com.sky.result.PageResult;import com.sky.result.Result;import com.sky.service.EmployeeService;import com.sky.utils.JwtUtil;import com.sky.vo.EmployeeLoginVO;import io.swagger.annotations.ApiOperation;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.HashMap;import java.util.Map;/** * 员工管理 */@RestController@RequestMapping("/admin/employee")@Slf4jpublic class EmployeeController {    @Autowired    private EmployeeService employeeService;//    @Autowired//    private JwtProperties jwtProperties;////    /**//     * 登录//     *//     * @param employeeLoginDTO//     * @return//     *///    @PostMapping("/login")//    public Result login(@RequestBody EmployeeLoginDTO employeeLoginDTO) {//        log.info("员工登录:{}", employeeLoginDTO);////        Employee employee = employeeService.login(employeeLoginDTO);////        //登录成功后,生成jwt令牌//        Map claims = new HashMap();//        claims.put(JwtClaimsConstant.EMP_ID, employee.getId());//        String token = JwtUtil.createJWT(//                jwtProperties.getAdminSecretKey(),//                jwtProperties.getAdminTtl(),//                claims);////        EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder()//                .id(employee.getId())//                .userName(employee.getUsername())//                .name(employee.getName())//                .token(token)//                .build();////        return Result.success(employeeLoginVO);//    }////    /**//     * 退出//     *//     * @return//     *///    @PostMapping("/logout")//    public Result logout() {//        return Result.success();//    }////    @PostMapping//    @ApiOperation("新增员工")//    public Result save(@RequestBody EmployeeDTO employeeDTO){//        log.info("新增员工:{}",employeeDTO);//        return Result.success();//    }    @GetMapping("/page")    @ApiOperation("员工分页查询")    public Result page(EmployeePageQueryDTO employeePageQueryDTO){        log.info("员工分页查询,参数为{}",employeePageQueryDTO);        PageResult pageResult = employeeService.pageQuery(employeePageQueryDTO);        //返回给Result        //返回的对象是pageResult        return Result.success(pageResult);    }}

      注意,结果return的是Result.success(pageResult);

      结果返回的是pageResult对象

      在service层扩展一下分页查询方法

      这里pageQuery会报错,我们再一个分页查询接口EmployeeService中完善这个方法

      EmployeeService.java

      package com.sky.service;import com.sky.dto.EmployeeDTO;import com.sky.dto.EmployeeLoginDTO;import com.sky.dto.EmployeePageQueryDTO;import com.sky.entity.Employee;import com.sky.result.PageResult;public interface EmployeeService {    //Employee login(EmployeeLoginDTO employeeLoginDTO);    //void save(EmployeeDTO employeeDTO);    //分页查询    PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO);}

      实现这个接口

      EmployeeServiceImpl.java

      package com.sky.service.impl;import com.github.pagehelper.Page;import com.github.pagehelper.PageHelper;import com.sky.constant.MessageConstant;import com.sky.constant.PasswordConstant;import com.sky.constant.StatusConstant;import com.sky.context.BaseContext;import com.sky.dto.EmployeeDTO;import com.sky.dto.EmployeeLoginDTO;import com.sky.dto.EmployeePageQueryDTO;import com.sky.entity.Employee;import com.sky.exception.AccountLockedException;import com.sky.exception.AccountNotFoundException;import com.sky.exception.PasswordErrorException;import com.sky.mapper.EmployeeMapper;import com.sky.result.PageResult;import com.sky.service.EmployeeService;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.util.DigestUtils;import java.time.LocalDateTime;import java.util.List;@Servicepublic class EmployeeServiceImpl implements EmployeeService {    @Autowired    private EmployeeMapper employeeMapper;    /**     * 员工登录     *     * @param employeeLoginDTO     * @return     *///    public Employee login(EmployeeLoginDTO employeeLoginDTO) {//        String username = employeeLoginDTO.getUsername();//        String password = employeeLoginDTO.getPassword();////        //1、根据用户名查询数据库中的数据//        Employee employee = employeeMapper.getByUsername(username);////        //2、处理各种异常情况(用户名不存在、密码不对、账号被锁定)//        if (employee == null) {//            //账号不存在//            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);//        }////        //密码比对//        // TODO 后期需要进行md5加密,然后再进行比对//        if (!password.equals(employee.getPassword())) {//            //密码错误//            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);//        }////        if (employee.getStatus() == StatusConstant.DISABLE) {//            //账号被锁定//            throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);//        }////        //3、返回实体对象//        return employee;//    }////    @Override//    public void save(EmployeeDTO employeeDTO) {//        Employee employee=new Employee();////       //对象属性拷贝//        BeanUtils.copyProperties(employeeDTO,employee);////        //设置账号状态,默认正常状态//        employee.setStatus(StatusConstant.ENABLE);////        //设置密码//        //默认密码为123456//        employee.setPassword(DigestUtils.md5DigestAsHex(PasswordConstant.DEFAULT_PASSWORD.getBytes()));////        //设置当前记录的创建时间和修改时间//        employee.setCreateTime(LocalDateTime.now());//        employee.setUpdateTime(LocalDateTime.now());////        //设置当前记录创建人的id和修改人id//        employee.setCreateUser(BaseContext.getCurrentId());//        employee.setUpdateUser(BaseContext.getCurrentId());////        employeeMapper.insert(employee);//    }    //分页查询    public PageResult pageQuery(EmployeePageQueryDTO employeePageQueryDTO){        PageHelper.startPage(employeePageQueryDTO.getPage(),employeePageQueryDTO.getPageSize());        Page page=employeeMapper.pageQuery(employeePageQueryDTO);        long total=page.getTotal();        List records=page.getResult();        return new PageResult(total,records);    }}

      这里我们使用了Mybatis的pagehelper插件

      要使用这个插件,实现我们在pox.xml文件中导入下面的依赖

                        com.alibaba            druid-spring-boot-starter        

      使用这个插件,会把我们后面的sql语句进行动态拼接。类似于MySQL的动态sql,会动态的把limit关键字拼接进去,并且进行动态计算


      同理,这里pageQuery会报错,我们在接口DishMapper中完善这个方法,Mapper层一般与数据库有关

      package com.sky.mapper;import com.github.pagehelper.Page;import com.sky.annotation.AutoFill;import com.sky.dto.DishPageQueryDTO;import com.sky.entity.Dish;import com.sky.enumeration.OperationType;import com.sky.vo.DishVO;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Select;import org.springframework.beans.factory.annotation.Autowired;@Mapperpublic interface DishMapper {    /**     * 根据分类id查询菜品数量     * @param      * @return     *///    @Select("select count(id) from dish where category_id = #{categoryId}")//    Integer countByCategoryId(Long categoryId);//////    //插入菜品数据//    @AutoFill(value = OperationType.INSERT)//    void insert(Dish dish);//菜品分页查询    Page pageQuery(DishPageQueryDTO dishPageQueryDTO);}

      注意

      这里我们传入的是DishPageQueryDTO,我们看一下下图

      下面我们来编写动态sql

      对于动态sql,使用注解进行开发是比较麻烦的(因为我们要使用到动态标签),所以我们把这段sql写到xml映射文件中

      EmployeeMapper.xml

                  select * from employee                    --             动态拼接                and name like concat('%',#{name},'%')                            order by create_time desc    

      ⭐问题

      我们发现,界面展示的时间不是我们想要的 年–月–日,而是一大串数字,我们应该怎么解决呢

      使用下面的方法进行解决

      解决方法

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

      WebMvcConfiguration.java

      package com.sky.config;import com.sky.interceptor.JwtTokenAdminInterceptor;import com.sky.json.JacksonObjectMapper;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.service.ApiInfo;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import java.util.List;/** * 配置类,注册web层相关组件 */@Configuration@Slf4jpublic class WebMvcConfiguration extends WebMvcConfigurationSupport {    @Autowired    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;////    /**//     * 注册自定义拦截器//     *//     * @param registry//     *///    protected void addInterceptors(InterceptorRegistry registry) {//        log.info("开始注册自定义拦截器...");//        registry.addInterceptor(jwtTokenAdminInterceptor)//                .addPathPatterns("/admin/**")//                .excludePathPatterns("/admin/employee/login");//    }////    /**//     * 通过knife4j生成接口文档//     * @return//     *///    @Bean//    public Docket docket() {//        ApiInfo apiInfo = new ApiInfoBuilder()//                .title("苍穹外卖项目接口文档")//                .version("2.0")//                .description("苍穹外卖项目接口文档")//                .build();//        Docket docket = new Docket(DocumentationType.SWAGGER_2)//                .apiInfo(apiInfo)//                .select()//                .apis(RequestHandlerSelectors.basePackage("com.sky.controller"))//                .paths(PathSelectors.any())//                .build();//        return docket;//    }////    /**//     * 设置静态资源映射//     * @param registry//     *///    protected void addResourceHandlers(ResourceHandlerRegistry registry) {//        registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/");//        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");//    }//        //扩展springmvc的消息转换器    protected void extendMessageConverters(List

上一篇:弘速云怎么样?,新推出香港CTG(19元/月,2核/2G/40G SSD)/香港国际/美国PRO等建站VPS机型,新用户半价

下一篇:[数据结构]栈