最近参与一个功能, 有一个需求是要将菜单一次性展示在前台,但是菜单是分级的,最多可以有十级,不同的根菜单,又有着不同的深度。想了一些方法,但是不仅后台包装麻烦,前台拿值也麻烦。于是尝试用递归遍历,实现这颗树。
首先第一步先创建一个实体类,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 Listnodes = new LinkedList();
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 ListgetNodes() {
return nodes;
}
public void setNodes(Listnodes) {
this.nodes = nodes;
}
}
配置Mybatis的映射的Mapper.xml文件
select
from sd_pr_product_price where year = #{year} and Product_Price_Level= 1
select * from sd_pr_product_price where Product_Price_Parent_ID = #{Product_Price_ID}
然后在Dao层写相关的映射接口
ListqueryChildById(String id);
ListselectRoot(String year);
然后是Service层
@Override
public ListgetTree(String year) {
// 找到root节点
ListselectList = prProductPriceDao
.selectRoot(year);
// 返回的树list
Listlist = new ArrayList();
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 {
Listchild = prProductPriceDao
.queryChildById(priceNode.getNode().getProductPriceId());
ListtreeNode = getTreeNode(child);
for (PriceNodeTree node : treeNode) {
priceNode.getNodes().add(getChiledTree(node));
}
return priceNode;
}
}
private ListgetTreeNode(Listlist) {
ListchildPriceNodeTrees = new LinkedList();
// 包装成树节点
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 MapgetIndexTree() {
Mapresult = new HashMap();
try {
// 获取当前系统年份
String year = new SimpleDateFormat("yyyy").format(new Date());
Listtree = prProductPriceService.getTree(year);
result.put("data", tree);
result.put("flag", "success");
} catch (Exception e) {
result.put("flag", "error");
e.printStackTrace();
}
return result;
}
看看和前台结合的效果
这个功能只有十级菜单,而且数据量小,如果当数据量很大时,递归是很容易使内存溢出的。如果有大神想大更好的方法,可以提出来,我们共同探讨~