树结构的转化Demo
开发中,数据库中会存在树形结构数据。例如:菜单、商品分类、前台需要进行分级展示。下面做一个demo。
以看一下数据库中这颗树是怎么存的:
树的结构一目了然,这是一棵表示部门的树。
实体类:
- public class Department {
- private String id; //部门id
- private String pid; //父id
- private String text; //部门名称
- private List<Department> children; //用于存储子节点
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getPid() {
- return pid;
- }
- public void setPid(String pid) {
- this.pid = pid;
- }
- public String getText() {
- return text;
- }
- public void setText(String text) {
- this.text = text;
- }
- public List<Department> getChildren() {
- return children;
- }
- public void setChildren(List<Department> children) {
- this.children = children;
- }
- }
用于读取数据库中的数据,生成一个List,该list返回到前台时会转成json格式的数据,重点需要理解buildTree(),通过递归生成这棵树,基本实现原理是遍历树的某一层,获取每个节点的子节点们(一个list),然后将它作为父节点的一个chlidren属性set进去。
@Controller
@RequestMapping("/department")
public class DepartmentController {
@Resource
private DepartmentService departmentService;
/**
* 获取部门树形列表
*/
@RequestMapping(value = "/getTree.do", method = RequestMethod.POST)
@ResponseBody //此注解表明返回值跳过视图处理部分,直接写入 http response body中
public List<Department> getTree(){
List<Department> root = departmentService.findByPId("-1"); //获取根节点(获取的值存到list中)
return buildTree(root);
}
public List<Department> buildTree(List<Department> root){
for(int i=0;i<root.size();i++){
List<Department> children = departmentService.findByPid(root.get(i).getId()); //查询某节点的子节点(获取的是list)
buildTree(children);
root.get(i).setChildren(children);
}
return root;
}
}
服务层:
接口:
public interface DepartmentService
{
public List<Department> findByPid(String pid);
}
实现:
@Service("departmentServiceImpl")
public class DepartmentServiceImpl implements DepartmentService{
@Autowired
private DepartmentDao departmentDao;
@Override
public List<Department> findByPid(String pid) {
return departmentDao.findByPid(pid);
}
}
前台调用如下:
$(function(){
$('#tt').tree({
url: 'department/getTree.do',
loadFilter: function(data){
if (data.d){
return data.d;
} else {
return data;
}
}
});
});
在页面上如下显示:
总结:重点是递归的运用。
下面放类似的递归实现。
//递归
id parentid isparant text
0 -1 true ..
1 0 true ..
2 0 true ..
3 1 false ..
4 2 false ..
private List<?> getCatList(long parentId) {
//根据父节点id查找所有子节点
List<TbItemCat> list = itemCatMapper.selectByPid(parentId);
//返回值list
List resultList = new ArrayList<>();
//遍历集合向list中添加节点
for (TbItemCat tbItemCat : list) {
//判断是否为父节点
if (tbItemCat.getIsParent()) {
CatNode catNode = new CatNode();
catNode.setText(tbItemCat.getText());
catNode.setId(tbItemCat.getId());
//递归遍历下一层
catNode.setChildren(getCatList(tbItemCat.getId()));
resultList.add(catNode);
//如果是叶子节点
} else {
catNode.setText(tbItemCat.getText());
catNode.setId(tbItemCat.getId());
}
}
return resultList;
}