Mybatis collection 递归查询并自动装填所有子节点(多参数查询传入参数方法)

需求:项目中想实现无限下拉子菜单功能,后台就需要返回包括子节点的所有数据 

 Mybatis collection 递归查询并自动装填所有子节点(多参数查询传入参数方法)_第1张图片

Mybatis collection 递归查询并自动装填所有子节点(多参数查询传入参数方法)_第2张图片

数据库表结构如下:

Mybatis collection 递归查询并自动装填所有子节点(多参数查询传入参数方法)_第3张图片

上次是通过在java程序中递归不断通过父级id查询子节点实现的:

https://blog.csdn.net/lianzhang861/article/details/83783796

但这样需要不断连接和断开数据库,比较费时

mybatis可以在数据库内部实现递归查询被自动装填,由于省去了数据库连接步骤,访问速度会更快,但会增加数据库服务器压力,使用时根据实际情况定使用程序递归还是数据库递归

方式是使用 resultMap中的collection,此标签可以一对多级联


  
         //适用于不存在没有参数的构造方法
            
            
        
        //这个对象的主键
        //一对一级联
        //一对多级联
        //鉴别器
            
        
    

实现方法:

1.首先添加该表的实体类ArticleCategory

public class ArticleCategory {

    private String categoryId;

    private String categoryName;

    private String categoryParentId;
    //存放子节点
    private List subList;

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(String categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public List getSubList() {
        return subList;
    }

    public void setSubList(List subList) {
        this.subList = subList;
    }

    public String getCategoryParentId() {
        return categoryParentId;
    }

    public void setCategoryParentId(String categoryParentId) {
        this.categoryParentId = categoryParentId;
    }
}

2.controller调用

@ResponseBody
@RequestMapping(value = "getArticleCategoryTree2", produces = "text/plain;charset=UTF-8")
public String getArticleCategory2(@RequestParam Map params) {
    RetBase ret=new RetBase();
    params.put("categoryId","0");
    //List> list=this.getSubCategory(params);
    List list=articleService.getArticleCategory1(params);
    ret.setData(list);
    ret.setSuccess(true);
    return JSON.toJSONString(ret);
}

3.dao

public List> getArticleCategory(Map params);

 4.xml


    
    
    
    


5.查出的数据格式

Mybatis collection 递归查询并自动装填所有子节点(多参数查询传入参数方法)_第4张图片

注意:

1.collection 的column与id的column相同,property为实体类中子集合的名字,select与查询方法名字相同

2.查询时一定要将id和parentId都查出来,否则mybaits无法完成递归,我用*查就更没问题了。实体类中也要有父id那个属性

3.我从controller调用的时候已经传入了一个父id参数,然后mybatis递归时又自动将父id传给查询。但这个参数的名字可以和resultMap中的id名字不相同,也就是说如果我controller里面传的父id名字为 cc,select中改为

and t.category_parent_id = #{cc}

mybatis照样能查出子集合,所以这个参数名可以随便写

不过前台js解读数据的时候也得用递归方法解析数据,有点麻烦~~~

 

========== 华丽分割线 ==============

时间来到了2019.12.19

最近搞springboot项目中的菜单管理中又用到了这个,不过菜单由于有权限限制啥的,传入的参数比较多,查询就会出现问题,要不查不出来,要不就是子查询参数不生效,因为先前只用到一个父id参数,而且网上能找到的大部分例子都是一个参数例子,这次经过试验总结到collection多参数传入的方法


        //这个对象的主键
        
    
    

首先collection是用来递归查询一对多的,其次是参数传入的问题,column是用来传参数的,如果只有一个参数,直接写一个用来关联的字段名就行了,不管你传的参数叫啥,它都会把上次查出的结果的这个字段自动放到下一次查询 这个参数的位置,所以就会发现如果只有一个参数,你参数传啥名字都没事。


    
    
    
    


但如果你的查询有多个参数就不一样了,需要用这种写法了,前面是传入参数名,等号 后面是字段名字

例子:

1.传入的参数

params.put("menuParent", "0");
params.put("menuType", "menu");
params.put("userId", USER.getUserId());
List menuList = menuService.getMenuList(params);

2.xml


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    
    



上面例子我传入了三个参数,想要正常查询,就得在column中配置三个参数,虽然我的sql中还判断其他的参数,但实际没有用到的话就不必在column中配

每次查询到父级后就会把查到结果中对应的字段值 匹配 配置的 参数名,一一对应的设置为下一次查询的参数值。

这也就意味着你的参数必须存在于上一次的查询结果集中,但是对于菜单管理,需要传入userId 去查询菜单权限这种情况,菜单表中肯定没有userId这个字段,这就需要你在查询第一次的时候就手动加上这个字段:

按理说应该在实体类和resultMap映射也添加这个字段才对,但我测试的是即使 实体类和resultMap映射中没有这个字段也可以正常使用。

如果参数是常量似乎可以直接写,但是不能直接把#{参数}放到column中:

column="{menuParent=MENU_ID,menuType=MENU_TYPE,userId='111'}" 

总之多参数传入这么可以解决,暂时还没发现有啥正统的解决方法,其次关于是否分页有问题还没有测试,暂时先这样

你可能感兴趣的:(数据库)