一.简单分页实体案例

返回数据:

可以看到请求参数中包含页码,每页记录数,排序字段,是否升序,模糊检索字段,状态字段。为了包含这些字段,我们需要创建一个DTO对象来封装这些属性。但是我们思考后可以发现,原来的UserQueryDTO对象中就包含了name和status属性。而前四个属性属于分页查询的基本属性,分页查询基本上都会用到。为了保证代码的可复用性,我们定义一个PageQueryDTO来封装这些属性。
package com.itheima.mp.domain.dto;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
@ApiModel(description = "分页查询条件实体")
public class PageQueryDTO {@ApiModelProperty("当前页码")private Integer pageNum;@ApiModelProperty("每页记录数")private Integer pageSize;@ApiModelProperty("排序字段")private String sort;@ApiModelProperty("排序方式:asc-升序,desc-降序")private Boolean isAsc;
}
我们只要让UserQueryDTO继承PageQueryDTO即可。
package com.itheima.mp.domain.dto;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(description = "用户查询条件实体")
public class UserQueryDTO extends PageQueryDTO{@ApiModelProperty("用户名关键字")private String name;@ApiModelProperty("用户状态:1-正常,2-冻结")private Integer status;@ApiModelProperty("余额最小值")private Integer minBalance;@ApiModelProperty("余额最大值")private Integer maxBalance;
}
这样我们就构建好了分页查询的请求DTO对象。
接着我们来构建响应信息。
相应信息包含Long类型的total,即总记录数。Long类型的pages,即总页数。还有List<UserVO>类型的每页记录。其中UserVO类如下:
package com.itheima.mp.domain.vo;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.itheima.mp.domain.po.UserInfo;
import com.itheima.mp.enums.UserStatus;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;@Data
@ApiModel(description = "用户VO实体")
public class UserVO {@ApiModelProperty("用户id")private Long id;@ApiModelProperty("用户名")private String username;@ApiModelProperty("详细信息")@TableField(typeHandler = JacksonTypeHandler.class)private UserInfo info;@ApiModelProperty("使用状态(1正常 2冻结)")private UserStatus status;@ApiModelProperty("账户余额")private Integer balance;@ApiModelProperty("用户收货地址")private List<AddressVO> addresses;
}
明确了响应信息的构成,我们就可以实现了。
package com.itheima.mp.domain.vo;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.util.List;@Data
@ApiModel(description = "分页VO实体")
// 定义一个统一的分页结果
public class PageVO<T> {@ApiModelProperty("总记录数")private Long total;@ApiModelProperty("总页数")private Long pages;@ApiModelProperty("当前页数据")private List<T> records;
}
由于我们后续的分页响应信息都是这样的,因此我们将当前页的类型指定为泛型类型。以保证复用性。
定义好后我们就可以开始进行分页查询的逻辑实现了。
二.分页查询的逻辑实现
controller层
package com.itheima.mp.controller;import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.dto.UserQueryDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.AddressVO;
import com.itheima.mp.domain.vo.PageVO;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.annotations.Update;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/users")
@Api(tags = "用户管理接口")
@RequiredArgsConstructor // 创建构造方法,用来代替@Autowired(spring不推荐)进行依赖注入 @RequiredArgsConstructor会将类的每一个final字段或者non-null字段生成一个构造方法
public class UserController {private final IUserService userService; // 我们加上final修饰符,表示这个属性不能被修改@PostMapping@ApiOperation("新增用户")public void saveUser(@RequestBody UserFormDTO userFormDTO) {User user = BeanUtil.copyProperties(userFormDTO, User.class);userService.save(user);}@DeleteMapping("/{id}")@ApiOperation("删除用户")public void deleteUser(@ApiParam("用户id") @PathVariable("id") Long id) {userService.removeById(id);}// @GetMapping("/{id}")
// @ApiOperation("根据id查询用户")
// public UserVO getUserById(@ApiParam("用户id") @PathVariable("id") Long id) {
// User user = userService.getById(id);
// return BeanUtil.copyProperties(user, UserVO.class);
// }@GetMapping("/{id}")@ApiOperation("根据id查询用户及其收货地址")public UserVO getUserById(@ApiParam("用户id") @PathVariable("id") Long id) {return userService.getByIdWithAddress(id);}@GetMapping@ApiOperation("根据id批量查询")public List<UserVO> getUserList(@RequestParam("ids") List<Long> ids) {return userService.getUsersAndAddresses(ids);}@PutMapping("/{id}/deduction/{money}")@ApiOperation("用户余额扣减")public void updateUser(@PathVariable("id") Long id,@PathVariable("money") Integer money) {userService.updateBalance(id, money);}@GetMapping("/list")@ApiOperation("根据复杂条件查询用户")public List<UserVO> queryUsers (UserQueryDTO userQueryDTO) {// 1.查询用户数据List<User> users = userService.queryList(userQueryDTO.getName(), userQueryDTO.getStatus(), userQueryDTO.getMinBalance(), userQueryDTO.getMaxBalance());// 2.返回数据return BeanUtil.copyToList(users, UserVO.class);}@GetMapping("/page")@ApiOperation("根据复杂条件分页查询用户接口")public PageVO<UserVO> queryUsersPage (UserQueryDTO userQueryDTO) {return userService.queryListPage(userQueryDTO);}
}
Service层
接口
package com.itheima.mp.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.mp.domain.dto.UserQueryDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.AddressVO;
import com.itheima.mp.domain.vo.PageVO;
import com.itheima.mp.domain.vo.UserVO;import java.util.List;public interface IUserService extends IService<User> {void updateBalance(Long id, Integer money);List<User> queryList(String name, Integer status, Integer minBalance, Integer maxBalance);UserVO getByIdWithAddress(Long id);List<UserVO> getUsersAndAddresses(List<Long> ids);PageVO<UserVO> queryListPage(UserQueryDTO userQueryDTO);
}
实现类
package com.itheima.mp.service.Impl;import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.itheima.mp.domain.dto.UserQueryDTO;
import com.itheima.mp.domain.po.Address;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.AddressVO;
import com.itheima.mp.domain.vo.PageVO;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.enums.UserStatus;
import com.itheima.mp.mapper.UserMapper;
import com.itheima.mp.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.*;
import java.util.stream.Collectors;// 要先继承,再实现接口
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic PageVO<UserVO> queryListPage(UserQueryDTO userQueryDTO) {// 1.创建Page对象,指定当前页码和每页记录数Page<User> page = new Page<>(userQueryDTO.getPageNum(), userQueryDTO.getPageSize());// 2.设置排序字段和排序方式if (userQueryDTO.getSort() != null) {page.addOrder(new OrderItem(userQueryDTO.getSort(), userQueryDTO.getIsAsc()));} else {// 如果前端不传入排序字段和排序方式,则默认根据更新时间进行降序排序page.addOrder(new OrderItem("update_time", false));}// 3.将Page查询条件封装进QueryWrapperPage<User> p = lambdaQuery().like(User::getUsername, userQueryDTO.getName()).eq(User::getStatus, userQueryDTO.getStatus()).page(page);// 4.获取查询结果// 4.1 获取总页数Long pages = p.getPages();// 4.2 获取总记录数Long total = p.getTotal();// 4.3 获取当前页数据List<User> records = p.getRecords();// 5.封装PageVOPageVO<UserVO> pageVO = new PageVO<>();pageVO.setPages(pages);pageVO.setTotal(total);if (records == null) {pageVO.setRecords(Collections.emptyList());return pageVO;}// 6.如果分页查询结果不为空,将当前页数据转换成UserVOList<UserVO> userVOS = BeanUtil.copyToList(records, UserVO.class);pageVO.setRecords(userVOS);return pageVO;}
}
我们使用lambdaQuery()方法来进行分页查询,首先使用like模糊匹配来进行用户名的匹配。接着使用eq判断状态码是否相等。最后连接page方法进行分页查询,其中page方法中要获取一个Page类型的对象,因此我们定义一个Page类型的对象,并指定泛型为User。在定义好的Page对象中传入页码和每页记录数,然后判断前端是否传入排序字段,如果传入就按照排序字段和排序方式进行排序,如果没有传入就默认按照更新时间进行降序排序。然后将定义好的Page对象传入lambdaQuery()方法。
最后获取总记录数,总页数和当前页的分页结果,因为是List<User>对象,要转换成List<UserVO>对象,使用BeanUtil工具类的copyToList方法进行转换。
最后将获取到的数据封装到PageVO<UserVO>对象中返回。
三.测试

分页查询成功。