项目使用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()方法拷贝数据