MyBatisPlus分页插件查跨表的分页(SpringBoot环境)

问题描述

我们知道MyBatisPlus的分页插件是操作对应的表来查询的,如果要展示的数据跨表,该如何查询展示?


场景模拟

假设有两张表菜品表和分类表,而展示菜品时,不但需要菜品信息,还要需要分类表的分类名称

需要用菜品表记录的分类表的category_id来查询分类表的分类名称

sql代码如下:

#分类表
CREATE TABLE `category` (
  `id` BIGINT(20) NOT NULL COMMENT '主键',
  `type` INT(11) DEFAULT NULL COMMENT '类型   1 菜品分类 2 套餐分类',
  `name` VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '分类名称',
  `sort` INT(11) NOT NULL DEFAULT '0' COMMENT '顺序',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  `update_time` DATETIME NOT NULL COMMENT '更新时间',
  `create_user` BIGINT(20) NOT NULL COMMENT '创建人',
  `update_user` BIGINT(20) NOT NULL COMMENT '修改人',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `idx_category_name` (`name`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品及套餐分类';

#菜品表
CREATE TABLE `dish` (
  `id` BIGINT(20) NOT NULL COMMENT '主键',
  `name` VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '菜品名称',
  `category_id` BIGINT(20) NOT NULL COMMENT '菜品分类id',
  `price` DECIMAL(10,2) DEFAULT NULL COMMENT '菜品价格',
  `code` VARCHAR(64) COLLATE utf8_bin NOT NULL COMMENT '商品码',
  `image` VARCHAR(200) COLLATE utf8_bin NOT NULL COMMENT '图片',
  `description` VARCHAR(400) COLLATE utf8_bin DEFAULT NULL COMMENT '描述信息',
  `status` INT(11) NOT NULL DEFAULT '1' COMMENT '0 停售 1 起售',
  `sort` INT(11) NOT NULL DEFAULT '0' COMMENT '顺序',
  `create_time` DATETIME NOT NULL COMMENT '创建时间',
  `update_time` DATETIME NOT NULL COMMENT '更新时间',
  `create_user` BIGINT(20) NOT NULL COMMENT '创建人',
  `update_user` BIGINT(20) NOT NULL COMMENT '修改人',
  `is_deleted` INT(11) NOT NULL DEFAULT '0' COMMENT '是否删除',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `idx_dish_name` (`name`)
) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='菜品管理';

对应的两个表的实体类

/**
 * 分类
 */
@Data
public class Category implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;


    //类型 1 菜品分类 2 套餐分类
    private Integer type;


    //分类名称
    private String name;


    //顺序
    private Integer sort;


    //创建时间
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;


    //更新时间
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;


    //创建人
    @TableField(fill = FieldFill.INSERT)
    private Long createUser;


    //修改人
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;
}


/**
 菜品
 */
@Data
public class Dish implements Serializable {

    private static final long serialVersionUID = 1L;

    private Long id;


    //菜品名称
    private String name;


    //菜品分类id
    private Long categoryId;


    //菜品价格
    private BigDecimal price;


    //商品码
    private String code;


    //图片
    private String image;


    //描述信息
    private String description;


    //0 停售 1 起售
    private Integer status;


    //顺序
    private Integer sort;


    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;


    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;


    @TableField(fill = FieldFill.INSERT)
    private Long createUser;


    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;


    //是否删除
    private Integer isDeleted;

}

解决方案:

建立一个新的实体类对象,将要返回的属性都写上面,其实就是继承菜品类再扩展一个分类名字

专业的术语称之为dto类,一般将此类型的类专一放在dto包下

新建的dto类如下:

@Data
public class DishDto extends Dish {//继承了Dish说明属性都继承过来了

    //下面的属性名称因为前端的分类的name就是categoryName
    //所以我这里返回的属性名称也要是categoryName,名字要一一对应的
    private String categoryName;
}



前端的这个属性的代码
<el-table-column
    prop="categoryName"
    label="菜品分类"
></el-table-column>

然后进行业务层基于MyBatisPlus的分页插件进行封装展示

下面代码讲解:

步骤1、先当成单表分页,将对应的菜品类分页查询的Page分页对象查询出来

步骤2、将菜品类分页对象的值,赋值给新建的dto类的分页对象

        赋值步骤:

                打开Page源码可知,只有List类型的属性records是分装展示的信息,其它的都一样。

                步骤1、拷贝除了分装展示的信息属性records值之外的所有属性,使用现成的拷贝属性的工具类BeanUtils,该工具类是Springboot提供的,具体调用的方法BeanUtils.copyProperties(被拷贝的对象,接收的对象,拷贝忽略属性的字符串);

                步骤2、菜品分页对象的分装展示的信息属性records在拷贝的基础上使用菜品中的分类id属性查询出对应的分类名称,并存入新的dto类里,最后放在对应的dto类的分页对象,然后进行dto类的分页对象的返回实现业务!

代码如下:

/**
     * 菜品信息分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(int page,int pageSize,String name){
        //构造分页构造器对象
        Page<Dish> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //如果name是空就直接查询全部,如果name不为空,就执行由name筛选条件的sql语句
        queryWrapper.like(name != null,Dish::getName,name);
        queryWrapper.orderByDesc(Dish::getUpdateTime);//按更新时间排序
        dishService.page(pageInfo,queryWrapper);

        //对象拷贝,因为没有categoryName,所以要把分页的信息查询过来后,所有信息都拷贝到Page<DishDto>
        Page<DishDto> dishDtoPage = new Page<>();//创建这个分页对象
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");//除了里面的records属性将信息全部拷贝一份
        List<Dish> records = pageInfo.getRecords();//将对应分装分页类的封装属性的List拿到,然后慢慢赋值
        List<DishDto> list = new ArrayList();
        for(Dish item: records){
            Long categoryId = item.getCategoryId();//找到List中每一个CategoryId
            Category category = categoryService.getById(categoryId);//Category表中进行查询
            String categoryName = category.getName();//找到对应Category表中的分类名称
            DishDto dishDto = new DishDto();
            dishDto.setCategoryName(categoryName);//先添加CategoryName属性的值
            BeanUtils.copyProperties(item,dishDto);//将dish的属性全部拷贝进去
            list.add(dishDto);//最后将封装好的对象全部添加到对应的List中
        }
        dishDtoPage.setRecords(list);
        return R.success(dishDtoPage);
    }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值