最近参与一个功能, 有一个需求是要将菜单一次性展示在前台,但是菜单是分级的,最多可以有十级,不同的根菜单,又有着不同的深度。想了一些方法,但是不仅后台包装麻烦,前台拿值也麻烦。于是尝试用递归遍历,实现这颗树。
首先第一步先创建一个实体类,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;
}看看和前台结合的效果
这个功能只有十级菜单,而且数据量小,如果当数据量很大时,递归是很容易使内存溢出的。如果有大神想大更好的方法,可以提出来,我们共同探讨~
本文介绍了如何使用Java的SSM框架,通过递归遍历方式来构建多级菜单,解决了菜单分级展示的问题。文章详细阐述了从创建实体类、配置Mapper.xml、实现Service层到Controller层的步骤,并展示了与前端结合的效果。虽然此方法适用于数据量小的情况,但作者也指出,面对大量数据时可能存在内存溢出风险,欢迎读者提供更优解决方案。
728

被折叠的 条评论
为什么被折叠?



