SSM实现树形菜单
SSM框架完成单表数据树形菜单实现
任务背景:
- 最近在搭建基于SSM种子项目框架时,遇到了树形菜单加载问题。特此把解决的问题方案记录下去,供其他小伙伴参考和日后回顾。
方案分析
- 方案选择
- 一次性加载完,返回前台需要的数据结构
- 点击加载,默认记载根层级的菜单。后续点击那一级菜单加载其下的子节点
- 对节点进行查询,删除,修改,增加
- 方案实现
- 在这里只分析一次性加载实现
- 对节点进行查询,删除,修改,增加
具体实现
- 表、数据资料
-
数据库
-
设置主键Id和parent_id的级联关
直接撸起代码干起:
-
实体类
/** * 编号 */ private Long id; /** * 名称 */ private String name; /** * 父级Id */ private Long parentId; /** * 子节点集合 */ List<Node> chilidren; public Node() { } public Node(Long id, String name, Long parentId, List<Node> chilidren) { this.id = id; this.name = name; this.parentId = parentId; this.chilidren = chilidren; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getParentId() { return parentId; } public void setParentId(Long parentId) { this.parentId = parentId; } public List<Node> getChilidren() { return chilidren; } public void setChilidren(List<Node> chilidren) { this.chilidren = chilidren; }
-
Dao层和service层一样
int insert(Node node); List<Node> getNodeTree(); List<Node> listChild(Long id); Node selectById(Long id); int updateById(Node node); int deleteById(Long... id);
-
Impl实现层
@Autowired private NodeDao nodeDao; @Override public int insert(Node node) { return nodeDao.insert(node); } @Override public List<Node> getNodeTree() { return nodeDao.getNodeTree(); } @Override public List<Node> listChild(Long id) { return nodeDao.listChild(id); } @Override public Node selectById(Long id) { return nodeDao.selectById(id); } @Override public int updateById(Node node) { return nodeDao.updateById(node); } @Override public int deleteById(Long... id) { return deleteById(id); }
-
Controlle层
-
@RestController @RequestMapping("/api/node") public class NodeController extends BaseApiController { @Autowired private NodeService nodeService; @GetMapping("/listChild") public Map<String,Object>listChild(@RequestParam Long id){ return onDataResp(nodeService.listChild(id)); } @GetMapping("/tree") public Map <String,Object> tree(){ return onDataResp(nodeService.getNodeTree()); } @GetMapping("/selectById") public Map <String,Object> selectById(@RequestParam Long id){ return onDataResp(nodeService.selectById(id)); } @GetMapping("/insert") public Map <String,Object> insert(@RequestParam Long parent_id,@RequestParam String name){ Node node = new Node(); node.setParentId(parent_id); node.setName(name); nodeService.insert(node); return onDataResp("添加成功"); } @GetMapping("/update") public Map <String,Object> update(@RequestParam Long id,@RequestParam Long parent_id,@RequestParam String name){ Node node = new Node(); node.setId(id); node.setParentId(parent_id); node.setName(name); if (nodeService.updateById(node) >0) return onSuccessRep("修改成功"); return onBadResp("修改失败"); } @GetMapping("delete") public Map<String,Object>delete(@RequestParam Long id){ nodeService.deleteById(id); return onBadResp("删除节点成功");
-
重点的Mapper.xml文件
<resultMap id="ParentTreeResultMap" type="com.my.blog.bean.Node"> <result column="id" property="id"/> <result column="name" property="name"/> <result column="parent_id" property="parentId"/> <collection column="id" property="chilidren" select="listChild" ofType="com.my.blog.bean.Node" /> </resultMap> <resultMap id="listChildResultMap" type="com.my.blog.bean.Node"> <result column="id" property="id"/> <result column="name" property="name"/> <result column="parent_id" property="parentId"/> <collection column="id" property="chilidren" select="listChild" ofType="com.my.blog.bean.Node" /> </resultMap> <insert id="insert"> INSERT INTO node(name,parent_id) VALUES (#{name},#{parentId}) </insert> //子级节点查询(listChild) <select id="listChild" resultMap="listChildResultMap"> SELECT id,name FROM node WHERE parent_id = #{id} </select> <select id="selectById" resultMap="ParentTreeResultMap"> SELECT id,name FROM node WHERE id=#{id} </select> //父级节点查询 <select id="getNodeTree" resultMap="ParentTreeResultMap"> SELECT id,name FROM node WHERE parent_id IS null </select> <update id="update"> UPDATE node <set> <if test="name!=null"> name=#{name},</if> <if test="parentId !=null"> parent_id=#{parentId}</if> </set> WHERE id=#{id} </update> <delete id="delete"> DELETE FROM node WHERE id IN <foreach collection="array" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </delete>
Mybatis之高级映射collection (递归查出树形数据 )
- 描述:利用Mybatis高级的映射关系,利用collection一对多关系,先查出父级节点方法: getNodeTree()(我的数据库父级节点设计为null)
- 再去找字节级节点方法: listChild()递归查出树形菜单
结果的实现和展示:
-
展示图片
-
Json数据
{ "code": 200, "data": [ { "id": 1, "name": "一级节点A", "chilidren": [ { "id": 4, "name": "二级节点AA", "chilidren": [ { "id": 7, "name": "三级节点AAA", "chilidren": [ ] }, { "id": 8, "name": "三级节点aaa", "chilidren": [ ] } ] }, { "id": 5, "name": "二级节点aa", "chilidren": [ ] } ] }, { "id": 2, "name": "一级节点a", "chilidren": [ { "id": 6, "name": "二级节点BB", "chilidren": [ { "id": 9, "name": "三级节点BBB", "chilidren": [ ] } ] } ] }, { "id": 3, "name": "一级节点B", "chilidren": [ ] }
]
}
总结:
利用Mybatis的collection标签进行一对多递归查询树形数据结构,先查出父级节点再查询子级节点。数据库设置联级关系,达到父级节点和子级可以同时一起删除,完成树形查单的增删查改。(第一次写博客,希望大家能够支持和指出问题所有)