问题:

项目使用spring boot整合MP技术 遇到多表查询问题

*现在有一个实体类封装的是A的数据–对应的是数据库A表里的数据,
Adto里面继承了A的属性,并且增加了一些属性—都是需要通过查询与A表有关联的表来获得的。
*分页查询的时候我们通过AService.getPage(page, pageSize)查询后返回的数据是IPage, 但是我们还要查询别的表获得其他属性填充到Adto里,最后给前端返回的数据应该是IPage,这时候怎么办?

思考:

方法一:我们知道IPage类里有很多属性,其中record里面封装的是我们要展示的数据,那我们可以新建一个IPage,把原来的IPage的数据拷贝进去,再查询其他表得到属性设置属性。可是其实我们仅仅只要改变IPage类的record属性,其他属性都要统统拷贝了一遍,有其他方法吗?
方法二:其实mybatis-plus早已为我们解决这个问题了,IPage中有一个convert方法。

解决:

我看到IPage中有一个convert方法,直觉告诉我感觉会解决我的问题,于是查了查用法。

MP自动把Do填充到Vo中,还可以在代码块中使用set方法填充Vo的变量。

public IPage<UserVO> list(PageRequest request) {
	IPage<UserDO> page = new Page(request.getPageNum(), request.pageSize());
	LambdaQueryWrapper<UserDO> qw = Wrappers.lambdaQuery();
	page  = userMapper.selectPage(page, qw);
	return page.convert(u->{ 
		UserVO v = new UserVO();
		BeanUtils.copyProperties(u, v);
		return v;
});
}

注意:u是原来iPage里面封装的数据,v是tdo类数据
BeanUtils.copyProperties(u, v); 将u拷贝进v里
于是看了上面的用法我解决了我的问题

我的案例解决:

简单记录一下我自己的问题解决过程

有一个dish(菜品类)里面没有category属性,还有一个category(菜品类型),想将每一个dish的category查出来封装到dishDto类里:

简单看一下dish和dishDto实体类

@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;
}
@Data
public class DishDto extends Dish {
    //口味
    private List<DishFlavor> flavors = new ArrayList<>();
    //分类
    private String categoryName;

    private Integer copies;
}
    @Override
    public IPage<DishDto> getPage(Integer page, Integer pageSize, DishDto dish) {
        //查询dish表
        IPage<Dish> iPage = new Page<>(page,pageSize);
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.like(Strings.isNotEmpty(dish.getName()),Dish::getName,dish.getName());
        //添加排序条件
        lqw.orderByDesc(Dish::getUpdateTime);
        iPage = dishMapper.selectPage(iPage, lqw);

        //mp提供了convert方法,将数据重新封装
        return iPage.convert(u->{
            DishDto v = new DishDto();
            Category category = categoryMapper.selectById(u.getCategoryId());//查询属性
            if (category!=null){
                v.setCategoryName(category.getName());//设置属性
            }
            BeanUtils.copyProperties(u, v);//拷贝
            return v;
        });
    }

总结:
本来封装Dish的iPage,是无法放入DishDto的,如果要新建一个放DishDto的Ipage,需要拷贝原来的Ipage
用convert方法将本来封装Dish的iPage,变成了封装DishDto的IPge,无需新建IPage再拷贝
将dto的属性查询后填充好,再把原来的属性拷贝进去
用BeanUtils.copyProperties()方法拷贝数据

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐