SSM递归遍历实现树形菜单

本文介绍了如何使用Java的SSM框架,通过递归遍历方式来构建多级菜单,解决了菜单分级展示的问题。文章详细阐述了从创建实体类、配置Mapper.xml、实现Service层到Controller层的步骤,并展示了与前端结合的效果。虽然此方法适用于数据量小的情况,但作者也指出,面对大量数据时可能存在内存溢出风险,欢迎读者提供更优解决方案。


  最近参与一个功能, 有一个需求是要将菜单一次性展示在前台,但是菜单是分级的,最多可以有十级,不同的根菜单,又有着不同的深度。想了一些方法,但是不仅后台包装麻烦,前台拿值也麻烦。于是尝试用递归遍历,实现这颗树。


首先第一步先创建一个实体类,TreeNode包装与表对应的实体类,这里对应的实体类的是PrProductEntity

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

public class PriceNodeTree implements Serializable{
	
	
	private static final long serialVersionUID = 724163273641931548L;
	private Integer pid;
	private PrProductPriceEntity node;
	private List<PriceNodeTree> nodes = new LinkedList<PriceNodeTree>();

	public Integer getPid() {
		return pid;
	}

	public void setPid(Integer pid) {
		this.pid = pid;
	}

	public PrProductPriceEntity getNode() {
		return node;
	}

	public void setNode(PrProductPriceEntity node) {
		this.node = node;
	}

	public List<PriceNodeTree> getNodes() {
		return nodes;
	}

	public void setNodes(List<PriceNodeTree> nodes) {
		this.nodes = nodes;
	}

	

}




配置Mybatis的映射的Mapper.xml文件

<select id="selectRoot" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
     from sd_pr_product_price where year = #{year} and  Product_Price_Level= 1
  </select>

<select id="queryChildById" parameterType="java.lang.String" resultMap="BaseResultMap">
    select * from sd_pr_product_price where Product_Price_Parent_ID = #{Product_Price_ID}
  </select>

然后在Dao层写相关的映射接口

List<PrProductPriceEntity> queryChildById(String id);
List<PrProductPriceEntity> selectRoot(String year);

然后是Service层

@Override
	public List<PriceNodeTree> getTree(String year) {
		// 找到root节点
		List<PrProductPriceEntity> selectList = prProductPriceDao
				.selectRoot(year);
		// 返回的树list
		List<PriceNodeTree> list = new ArrayList<PriceNodeTree>();
		for (PrProductPriceEntity pr : selectList) {
			PriceNodeTree priceNodeTree = new PriceNodeTree();
			priceNodeTree.setNode(pr);

			if (prProductPriceDao.queryChildById(pr.getProductPriceId()) == null) {
				list.add(priceNodeTree);
			} else {

				
				PriceNodeTree chiledTree = getChiledTree(priceNodeTree);
				list.add(chiledTree);

			}

		}
		return list;

	}

	public PriceNodeTree getChiledTree(PriceNodeTree priceNode) {
		// 如果没有孩子了 为底层节点
		if (prProductPriceDao.queryChildById(priceNode.getNode()
				.getProductPriceId()) == null) {

			return priceNode;
		} else {
			List<PrProductPriceEntity> child = prProductPriceDao
					.queryChildById(priceNode.getNode().getProductPriceId());
			List<PriceNodeTree> treeNode = getTreeNode(child);
			for (PriceNodeTree node : treeNode) {

				priceNode.getNodes().add(getChiledTree(node));
			}
			return priceNode;

		}

	}

	

	private List<PriceNodeTree> getTreeNode(List<PrProductPriceEntity> list) {
		List<PriceNodeTree> childPriceNodeTrees = new LinkedList<PriceNodeTree>();
		// 包装成树节点
		for (PrProductPriceEntity pr : list) {
			PriceNodeTree tempNode = new PriceNodeTree();
			tempNode.setNode(pr);
			childPriceNodeTrees.add(tempNode);

		}

		return childPriceNodeTrees;

	}


最后,再是controller层


// 返回递归树,显示在首页
	@RequestMapping(value = "/getIndexTree", method = RequestMethod.GET)
	public @ResponseBody Map<String, Object> getIndexTree() {
		Map<String, Object> result = new HashMap<String, Object>();
		try {

			// 获取当前系统年份
			String year = new SimpleDateFormat("yyyy").format(new Date());
			List<PriceNodeTree> tree = prProductPriceService.getTree(year);

			result.put("data", tree);
			result.put("flag", "success");
		} catch (Exception e) {
			result.put("flag", "error");
			e.printStackTrace();
		}
		return result;
	}


看看和前台结合的效果




这个功能只有十级菜单,而且数据量小,如果当数据量很大时,递归是很容易使内存溢出的。如果有大神想大更好的方法,可以提出来,我们共同探讨~

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值