mybatis 单表自关联 实现树结构的几种方式

javaBean如下:

public class Permission implements Serializable {
    private Integer id;
    private String name;
    private String icon;
    private String url;
    private boolean open;//树叶是否打开
    private Integer pid;//父id
    private boolean checked;//是否被选中
    private List children =new ArrayList();//子集合
}

第一种:使用mybatis映射实现:
1.在mapper映射文件中配置:

 

  
  
  
  
  
  
  



2.Service层:调用selectRoot方法

public List selectRoot() {
    return permissionMapper.selectRoot();
}

3.Controller层:

@RequestMapping("/permissionALL")
@ResponseBody
public List all(){
    List list= permissionService.selectRoot();
    return list;
}   

结果得到的:在这里插入图片描述

第二种:通过递归实现:
1.mapper.xml配置:


  
  
  
  
  


2.Service层:

public List selectChildren(Integer id) {
   	return permissionMapper.selectChildren(id);
 }

3.Controller层:

@RequestMapping("/initPermission1")
@ResponseBody
public Permission initPermission1(){
    Permission permission=new Permission ();
    try{
        permission.setId(1);//这个地方应该通过数据库查询出根节点,因为根节点id在数据库是1,所以偷了一下懒
        queryChildPermissions(permission);//递归得到全部节点
    }catch (Exception e){
        throw  e;
    }
    return permission;
}
private void queryChildPermissions (Permission permission){
    List children=  permissionService.selectChildren(permission.getId());//通过id查询子集合
    permission.setChildren(children);//将查询出来的子节点集合放入到permission集合中
    for(Permission innerChildren:children){        //遍历出子集合的子集合
        queryChildPermissions(innerChildren);      //放入到子节点的子集合中
    }
}

4.调用initPermission1方法,查询结果和第一种方式是一致的,这两种方式不建议使用,因为每一次执行递归都会发sql语句,对资源占有很大。

第三种:一次查出全部记录,通过嵌套循环遍历结果
1.mapper.xml配置;


  
  
  
  
  

 

2.Service层:

public List selectAll() {
    return permissionMapper.selectAll();
}

3.Controller层:

@RequestMapping("/initPermission2")
@ResponseBody
public Permission initPermission2(){

    Permission permission=new Permission ();
    List lists=permissionService.selectAll();//查询所有节点
    try{
        for(Permission ps:lists){//遍历节点
            Permission child=ps;
            if(ps.getPid().equals(0)||ps.getPid()==null){//获取根节点,Integer类型是包装类,判断对象引用
                permission=ps;//根节点
            }else{
                for (Permission innerpermission:lists){
                    if(child.getPid()==innerpermission.getId()){//如果节点的的pid和集合中某个节点的id一致
                        Permission parent=innerpermission;//将这个节点命名为父节点
                        parent.getChildren().add(child);//然后把child放入到它的父亲集合中
                        break;
                    }
                }
            }
        }
    }catch (Exception e){
        throw  e;
    }
            return permission;
}

查询的结果和前面两种的结果一致,一次查出所有数据,通过嵌套循环遍历得到结果,不需要频繁发送sql语句,但是如果数据多的话,循环的次数过多,会影响性能

第四种:一次查出所有数据,通过Map集合实现树结构

Service层和mapper.xml 同第三种方式
Controller层:

@RequestMapping("/initPermission")
@ResponseBody
public Permission initPermission(){
    Permission permission=new Permission ();
    List lists=permissionService.selectAll();//查询所有节点
    Map map=new HashMap();//将所有节点存入到map集合
    try{
        for(Permission ps:lists) {
           map.put(ps.getId(),ps);//将所有id做为key,Permission对象做值,存入到map集合
        }
        for(Permission ps:lists){//遍历所有节点
            Permission child=ps;
            if (child.getPid().equals(0)||child.getPid()==null){
                permission=ps;//取出根节点
            }else{
                Permission parent=map.get(child.getPid());//通过子节点的pid获取父节点
                parent.getChildren().add(child);//将子节点放入父节点中
            }
        }
    }catch (Exception e){
        throw  e;
    }
    return permission;
}

4种查询出来的结果都是一样的,相对而言通过Map实现树结构,效率是最高的

你可能感兴趣的:(mybatis 单表自关联 实现树结构的几种方式)