最近呢,一个小伙伴突然想查询菜单下面的所有子菜单,子菜单下面还有好几层套下去,小伙伴不想写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:
接下来,你试试应该就可以了。
注意:
1.如果想查询多个参数,修改column
column="{menuCode=menu_code,menuTypeDesc=menu_type_desc}"
2.如果是不能一条sql查出来,就修改collection里面的select值,
这边的sql直接查询的是list对象的信息
如果上述解决不了你的问题,可以在下方评论或者加个微信交流下,各位观众大老爷,求点赞,求三连~