Mybatis自查询递归查找子菜单

之前写过 java从数据库读取菜单,递归生成菜单树

今天才发现mybatis也可以递归查询子菜单

先看一下数据库

这里写图片描述

主键id,名称name,父id,和url

设计菜单类

public class Menu {
	// 菜单id
	private String id;
	// 父菜单id
	private String parentId;
	// 菜单名称
	private String name;
	// 菜单url
	private String url;
	// 子菜单
	private List<Menu> children;
	// 省去getter setter和toString方法
}

menuDao

public interface MenuDao {

	/**
	 * 递归查找所有
	 * 
	 * @return
	 */
	public List<Menu> findAllRecursion();
}

mapper.xml

最新的,可以无穷遍历

    <!-- 这里的id的值作为下面的查询返回结果resultMap的值 -->
    <!-- collection中的column属性可以为多个值,这里只有一个,它作为下面递归查询传递进去的参数 -->
    <!-- ofType和javaType属性正好联合构成了数据Bean类Category中的childrenList属性的数据类型 -->
    <!-- select的值为下面递归查询的select标签的id值 -->
    <resultMap type="Menu" id="menuTree">
        <id column="id" property="id"/>
        <result column="parent_id" property="parentId"/>
        <result column="name" property="name"/>
        <result column="url" property="url"/>
        <collection property="children" ofType="Menu" column="id" select="getMenuChildren"/>
    </resultMap>

    <!-- 先查询菜单根级目录 -->
    <!-- 这里的返回结果必须为resultMap,并且值为上面构建的resultMap的id的值 -->
    <select id="findAllRecursion" resultMap="menuTree">
        SELECT
            *
        FROM
            menu 
        WHERE
            parent_id IS NULL
    </select>

    <!-- 再利用上次查询结果colliection中column的值cid做递归查询,查出所有子菜单 -->
    <!-- 这里的返回结果必须为resultMap,并且值为上面构建的resultMap的id的值 -->
    <select id="getMenuChildren" resultMap="menuTree">
        SELECT
            *
        FROM
            menu 
        WHERE
            parent_id= #{id}
    </select>

这里写图片描述
Tip:最近发现通过mybatis递归查找子菜单如果菜单比较多会非常耗时,可以通过mybatis一次性把所有菜单查找出来,再通过程序构建菜单树
构建菜单树的文章地址
java从数据库读取菜单,递归生成菜单树

如果要使用 Mybatis 实现动态递归菜单查询 SQL,可以使用 Mybatis递归查询功能和动态 SQL 功能来实现。 下面是一个示例 SQL,可以根据传入的菜单 ID 查询菜单及其所有菜单: ``` WITH RECURSIVE temp_menu(id, parent_id, name, level, path) AS ( -- 查询指定菜单 SELECT id, parent_id, name, 1 AS level, CAST(id AS VARCHAR) AS path FROM menu WHERE id = #{menuId} UNION ALL -- 查询菜单 SELECT m.id, m.parent_id, m.name, tm.level + 1 AS level, CONCAT(tm.path, '-', m.id) AS path FROM menu m INNER JOIN temp_menu tm ON m.parent_id = tm.id ) SELECT id, parent_id, name, level, path FROM temp_menu ORDER BY path; ``` 在这个 SQL 中,使用了 WITH RECURSIVE 句和 UNION ALL 操作符来实现递归查询查询出指定菜单及其所有菜单。其中,temp_menu 是一个递归查询的临时表,用于存储查询结果,包含了菜单 ID、菜单名称、菜单级别和菜单路径等信息。使用了 CAST 和 CONCAT 函数来处理菜单路径。 在 Mybatis 中,可以使用 #{menuId} 占位符来接收传入的菜单 ID 参数,然后编写对应的 Mapper 接口和 XML 文件,使用动态 SQL 功能来拼接 SQL 语句,最终实现动态递归菜单查询。 例如,对应的 Mapper 接口和 XML 文件如下: ``` public interface MenuMapper { List<Menu> selectRecursiveMenu(Integer menuId); } ``` ``` <!-- MenuMapper.xml --> <select id="selectRecursiveMenu" resultMap="menuResultMap"> WITH RECURSIVE temp_menu(id, parent_id, name, level, path) AS ( -- 查询指定菜单 SELECT id, parent_id, name, 1 AS level, CAST(id AS VARCHAR) AS path FROM menu WHERE id = #{menuId} UNION ALL -- 查询菜单 SELECT m.id, m.parent_id, m.name, tm.level + 1 AS level, CONCAT(tm.path, '-', m.id) AS path FROM menu m INNER JOIN temp_menu tm ON m.parent_id = tm.id ) SELECT id, parent_id, name, level, path FROM temp_menu ORDER BY path; </select> ``` 在 XML 文件中,使用了 select 语句来定义 SQL 查询语句,并使用 resultMap 来映射查询结果集。使用了 #{menuId} 占位符来接收传入的菜单 ID 参数,并在 SQL 语句中使用动态 SQL 语句拼接查询语句。最后,定义了一个 selectRecursiveMenu 方法来调用该 SQL 语句,并返回查询结果。
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值