- 若不使用mybatisPlus进行上下级数据查询,纯用mybatis的话,则使用连表操作方式(自己连自己)查询,但是代码量会比较多,想知道mybatis如何来完成操作,具体可至如何完成数据字典
前端页面演示
- 此演示的是目的地的查询,目的地可能存在下级目的地和上级目的地
- 点击目的地数据,则显示到它的下级目的地
- 点击图中的
中国
之后则显示中国内的目的地,例如北京
,点击北京后也会显示相应的下级目的地,依次类推
准备工作
表结构
- 这里主要是有parent_id,作为此目的地的父级目的地的id
实体类
- 此处的
private List<Destination> children = new ArrayList<>();
是来存放此目的地
的下一级的所有目的地们
数据的 - 在myabtisPlus的操作中,因为children属性结构 并不和数据库表结构对应匹配,所以必须加
@TableField(exist = false)
注解,避免被sql编译而报错
qo高查类
- 一个公共的QueryObject类 用于被其他具体的qo类所继承
@Setter
@Getter
public class QueryObject implements Serializable {
private int currentPage = 1;
private int pageSize = 5;
private String keyword;
public String getKeyword(){
return StringUtils.hasLength(keyword)?keyword:null;
}
}
- DestinationQuery类继承QueryObject类,携带parentId属性,用作于实现上级查下级数据的过滤操作
@Setter
@Getter
public class DestinationQuery extends QueryObject {
private Long parentId;
}
控制器层
- 共享给前端页面的数据中
toasts
是吐司显示的数据,page
是加上了qo
的条件过滤并分页后的 目的地数据
业务实现方法
- queryPage(qo)方法,将过滤条件传入,过滤条件含有parentId,若不为空则进行相应过滤
- mybatisPlus中主要用wrapper进行条件设置,若qo有关键字keyword值则进行模糊查询过滤数据
- 若qo中有携带parentId值,则查找parentId是此qo的parentId值的目的地数据(也就是查子目的地集合出来)
- 若qo中没有携带parentId值,则查找parentId为空的目的地集合出来(也就是最上级的目的地集合)
- 最后将这些数据都分页过滤后给回前端
public Page<Destination> queryPage(DestinationQuery qo) {
Page<Destination> page = new Page<>(qo.getCurrentPage(),qo.getPageSize());
QueryWrapper wrapper = new QueryWrapper();
wrapper.like(StringUtils.hasLength(qo.getKeyword()),"name",qo.getKeyword())
.isNull(qo.getParentId()==null,"parent_id")
.eq(qo.getParentId()!=null,"parent_id",qo.getParentId());
return super.page(page,wrapper);
}
效果演示
递归方式实现吐司数据显示
说明
- 每次点击一个父级目的地,则会拼接这个吐司数据
- 吐司效果就是以下图,这里点击吐司数据链接也会让页面显示对应的子级目的地集合数据
前端遍历的代码演示
- 后端共享
toasts
数据(目的地数据集合)给前端 - 每个吐司数据在页面都作为一个链接,携带了自己的id在前端上,前端代码将此id赋值给DestinationQuery中的parentId的值(此操作不做演示),点击则会将DestinationQuery作为参数访问后端显示数据页面的url(就是’/list’),携带过滤条件来查询数据,则会显示此
吐司数据(目的地)
的子级目的地
集合数据 - 点击
根
则不携带parentId去访问后端显示页面的url,也就是查最上级的目的地数据集合
业务层实现方法
- 控制器层的部分截图
业务层方法queryToasts(Long destId)
调用了createToast
的递归方法完成功能实现
- 页面上,每次点击目的地,则将此目的地id作为qo中的parentId传入控制器中,然后控制器调用此方法接受此parentId,也就是以下的方法参数
destId
- 调用递归方法,传2个参数,参数一:放入一个空集合用来存放吐司数据,参数二:传入目的地id,将用于找出此id的所有上级数据作为吐司数据,放进参数一的集合中
public List<Destination> queryToasts(Long destId) {
List<Destination> list =new ArrayList<>();
// 递归方式
this.createToast(list,destId);
Collections.reverse(list);//反转
return list;
}
private void createToast(List<Destination> list,Long destId){
if (destId == null){
return;
}
Destination dest = super.getById(destId);
list.add(dest);
if (dest.getParentId()!=null){
this.createToast(list,dest.getParentId());
}
}