mybatis 一对多collection的使用 递归查询

最近呢,一个小伙伴突然想查询菜单下面的所有子菜单,子菜单下面还有好几层套下去,小伙伴不想写for循环查询,那样太臃肿了,那不巧了么,那不是
要来认真(shui)一篇了不~

那么首先说明下你看了这篇文章能学到什么
collection 的用法 – 解决递归查询、解决对象中包含List<对象> 一对多

1.格式

首先呢,我们想得到的格式是这样的:

[
    {
        "menuCode":"101",
        "menuName":"商品模块",
        "parentCode":"1",
        "menuUrl":null,
        "children":[
            {
                "menuCode":"10101",
                "menuName":"手机模块-子菜单",
                "parentCode":"101",
                "menuUrl":null,
                "children":[
                    {
                        "menuCode":"1010101",
                        "menuName":"iphone--子子菜单",
                        "parentCode":"10101",
                        "menuUrl":"iphone.html",
                        "children":[
                        ]
                    },
                    {
                        "menuCode":"1010102",
                        "menuName":"华为--子子菜单",
                        "parentCode":"10101",
                        "menuUrl":"华为phone.html",
                        "children":[
                        ]
                    }]
            },
            {
                "menuCode":"10201",
                "menuName":"电视模块-子菜单",
                "parentCode":"101",
                "menuUrl":"",
                "children":[
                    {
                        "menuCode":"1020102",
                        "menuName":"小米电视--子子菜单",
                        "parentCode":"10201",
                        "menuUrl":"小米tv.html",
                        "children":[
                        ]
                    }]
            }]
    }]

2.sql脚本:

那先准备下sql脚本:
DROP TABLE IF EXISTS `t_b_menu`;
CREATE TABLE `t_b_menu`  (
  `MENU_CODE` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单编码',
  `MENU_NAME` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单名称',
  `MENU_TYPE` tinyint(4) NULL DEFAULT NULL COMMENT '菜单类型(1菜单,2按钮)',
  `PARENT_CODE` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '父菜单编码',
  `SORT_INDEX` tinyint(4) NULL DEFAULT NULL COMMENT '排序编号',
  `MENU_URL` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '菜单URL',
  `STATUS` tinyint(4) NULL DEFAULT NULL COMMENT '状态',
  `VALID_TIME` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '生效时间',
  `INVALID_TIME` timestamp(0) NOT NULL DEFAULT '2037-12-31 23:59:59' COMMENT '失效时间',
  `CREATE_TIME` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `USER_ID` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人',
  PRIMARY KEY (`MENU_CODE`, `VALID_TIME`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;


INSERT INTO `t_b_menu` VALUES ('101', '商品模块', 1, '1', 1, NULL, 1, '2020-05-15 16:14:24', '2037-12-31 23:59:59', '2020-05-15 16:14:24', 'admin');
INSERT INTO `t_b_menu` VALUES ('10101', '手机模块-子菜单', 1, '101', 1, NULL, 1, '2020-05-15 16:14:24', '2037-12-31 23:59:59', '2020-05-15 16:14:24', 'admin');
INSERT INTO `t_b_menu` VALUES ('1010101', 'iphone--子子菜单', 1, '10101', 1, 'iphone.html', 1, '2020-05-15 16:14:24', '2037-12-31 23:59:59', '2020-05-15 16:14:24', 'admin');
INSERT INTO `t_b_menu` VALUES ('1010102', '华为--子子菜单', 1, '10101', 2, '华为phone.html', 1, '2020-05-15 16:14:24', '2037-12-31 23:59:59', '2020-05-15 16:14:24', 'admin');
INSERT INTO `t_b_menu` VALUES ('10201', '电视模块-子菜单', 1, '101', 1, '', 1, '2020-05-15 16:14:25', '2037-12-31 23:59:59', '2020-05-15 16:14:25', 'admin');
INSERT INTO `t_b_menu` VALUES ('1020102', '小米电视--子子菜单', 1, '10201', 2, '小米tv.html', 1, '2020-05-15 16:14:25', '2037-12-31 23:59:59', '2020-05-15 16:14:25', 'admin');

3.准备下model及对应的各层代码

这边主要就是xml文件的写法,其他都是一行调用,直接到mapper文件了,贴一下代码

/**
 * @author yang
 * 测试菜单
 * @date 2020/6/30
 */
public interface MenuMapper {

    List<MenuDto> getMenuInfo(String menuCode);

}

这边menucode传递的是父类的id,然后执行sql 找到子类及下面的数据

<resultMap id="resultSecondMapByRole" type="com.yang.demo.model.MenuDto">
        <result column="menu_code" jdbcType="VARCHAR" property="menuCode"/>
        <result column="menu_name" jdbcType="VARCHAR" property="menuName"/>
        <result column="menu_url" jdbcType="VARCHAR" property="menuUrl"/>
        <result column="parent_code" jdbcType="VARCHAR" property="parentCode"/>
    </resultMap>

   <resultMap id="resultMapByRole" type="com.yang.demo.model.MenuDto" extends="resultSecondMapByRole">
        <collection property="children" column="{menuCode=menu_code}"  ofType="com.yang.demo.model.MenuDto"
                    select="getMenuInfo">
        </collection>
    </resultMap>

    <select id="getMenuInfo"  resultMap="resultMapByRole">
        select a.menu_code, a.menu_name, a.menu_url,a.parent_code
        from t_b_menu as a
        where a.PARENT_CODE = #{menuCode,jdbcType=VARCHAR}
        order by a.sort_index
    </select>

那么来详细讲解下这边:
先贴一下实体类:

/**
 * @author yang
 * @desc 菜单实体类
 * @date 2020/6/30
 */
@ApiModel(value = "MenuDto", description = "菜单Model")
public class MenuDto {

    @ApiModelProperty(value = "菜单ID")
    private String menuCode;

    @ApiModelProperty(value = "菜单名称")
    private String menuName;

    @ApiModelProperty(value = "菜单父类ID")
    private String parentCode;

    @ApiModelProperty(value = "菜单链接")
    private String menuUrl;

    @ApiModelProperty(value = "子集合")
    private List<MenuDto> children;

    public String getMenuCode() {
        return menuCode;
    }

    public void setMenuCode(String menuCode) {
        this.menuCode = menuCode;
    }

    public String getMenuName() {
        return menuName;
    }

    public void setMenuName(String menuName) {
        this.menuName = menuName;
    }


    public String getParentCode() {
        return parentCode;
    }

    public void setParentCode(String parentCode) {
        this.parentCode = parentCode;
    }


    public String getMenuUrl() {
        return menuUrl;
    }

    public void setMenuUrl(String menuUrl) {
        this.menuUrl = menuUrl;
    }

    public List<MenuDto> getChildren() {
        return children;
    }

    public void setChildren(List<MenuDto> children) {
        this.children = children;
    }
}

接着图片讲解下sql:
杨磊讲解collection查询

接下来,你试试应该就可以了。
注意:
1.如果想查询多个参数,修改column
column="{menuCode=menu_code,menuTypeDesc=menu_type_desc}"
2.如果是不能一条sql查出来,就修改collection里面的select值,
这边的sql直接查询的是list对象的信息

如果上述解决不了你的问题,可以在下方评论或者加个微信交流下,各位观众大老爷,求点赞,求三连~

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值