java开发过程中遇到的新知识、重点、难点以及出错的解决方法的汇总
1.树形结构的基础知识 1.1节点类型
生成页面上的效果(下面的效果)需要用到zTree插件
约定:整个树形结构节点的层次最多只能有 3 级。
1.2 在数据库表中表示树形结构在数据库表的记录之间如果没办法建立起父子关系,在页面上显示树形结构就没有依据
1.2.1创建菜单的数据库表
create table t_menu
(
id int(11) not null auto_increment,
pid int(11),
name varchar(200),
url varchar(200),
icon varchar(200),
primary key (id)
);
1.2.2往菜单表中插入数据
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('1',NULL,'系统权限菜单','glyphicon glyphicon-th-list',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('2','1',' 控 制 面 板 ','glyphicon glyphicon-dashboard','main.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('3','1','权限管理','glyphicon glyphicon glyphicon-tasks',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('4','3',' 用 户 维 护 ','glyphicon glyphicon-user','user/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('5','3',' 角 色 维 护 ','glyphicon glyphicon-king','role/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('6','3',' 菜 单 维 护 ','glyphicon glyphicon-lock','permission/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('7','1',' 业 务 审 核 ','glyphicon glyphicon-ok',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('8','7','实名认证审核','glyphicon glyphicon-check','auth_cert/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('9','7',' 广 告 审 核 ','glyphicon glyphicon-check','auth_adv/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('10','7',' 项 目 审 核 ','glyphicon glyphicon-check','auth_project/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('11','1',' 业 务 管 理 ','glyphicon glyphicon-th-large',NULL);
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('12','11',' 资 质 维 护 ','glyphicon glyphicon-picture','cert/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('13','11',' 分 类 管 理 ','glyphicon glyphicon-equalizer','certtype/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('14','11',' 流 程 管 理 ','glyphicon glyphicon-random','process/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('15','11',' 广 告 管 理 ','glyphicon glyphicon-hdd','advert/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('16','11',' 消 息 模 板 ','glyphicon glyphicon-comment','message/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('17','11',' 项 目 分 类 ','glyphicon glyphicon-list','projectType/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('18','11',' 项 目 标 签 ','glyphicon glyphicon-tags','tag/index.htm');
INSERT INTO `t_menu` (`id`, `pid`, `name`, `icon`, `url`) VALUES('19','1',' 参 数 管 理 ','glyphicon glyphicon-list-alt','param/index.htm');
1.2.3关联方式(如何建立父子关系):根节点的 pid 为 null
1.3 在java类中表示树形结构1.3.1基本方式:在Menu类中使用List
- pid属性:找到父节点
- name属性:作为节点的名称
- icon属性:当前节点使用的图标
- open属性:控制节点是否默认打开
- url属性:点击节点时跳转的位置
2.1.1目标:将数据库中查询到的数据到页面上显示出来
2.1.2思路:数据库查询全部 → java对象组装 → 页面上使用zTree显示
2.1.3代码:逆向工程生成Menu、MenuExample、MenuMapper、MenuMapper.xml等
对生成的Menu做一些调整:
public Menu() {
}
public Menu(Integer id, Integer pid, String name, String url, String icon, List
2.1.4代码:将数据在 Java 代码中组装成树形结构
MenuServiceImpl中: @Override public ListgetAll() { return menuMapper.selectByExample(new MenuExample()); } MenuController中:改进前,要改进的原因是存在嵌套遍历,如果循环次数较多,对性能是一个极大的消耗 @ResponseBody @RequestMapping("/menu/get/whole/tree") public ResultEntity getWholeTreeOld(){ // 1.查询全部的Menu对象 List menuList = menuService.getAll(); // 2.声明一个变量用来存储找到的根节点 Menu root = null; // 3.遍历menuList for (Menu menu : menuList) { // 4.获取当前menu对象的pid Integer pid = menu.getPid(); // 5.检查pid是否为空 if(pid == null){ // 6.把当前正在遍历的这个menu对象复制给root root = menu; // 7.停止本次循环,继续执行下一次循环 continue ; } // 8.如果pid不为null,说明当前节点有父节点,找到父节点就可以进行组装,建立父子关系 for(Menu maybeFather : menuList){ // 9.获取maybeFather的id属性 Integer id = maybeFather.getId(); // 10.将子节点的pid和疑似父节点的id进行比较 if(Objects.equals(pid,id)){ // 11.将子节点存入父节点的children集合 maybeFather.getChildren().add(menu); // 12.找到即可停止运行循环 break; } } } // 13.经过上面的运算,根节点包含了整个树形结构,返回根节点就是返回整个树 return ResultEntity.successWithData(root); } MenuController中:改进后 @ResponseBody @RequestMapping("/menu/get/whole/tree") public ResultEntity getWholeTreeNew(){ // 1.查询全部的Menu对象 List menuList = menuService.getAll(); // 2.声明一个变量用来存储找到的根节点 Menu root = null; // 3.创建Map对象用来存储id和Menu对象的对应关系,便于查找父节点 Map menuMap = new HashMap<>(); // 4.遍历menuList填充menuMap for (Menu menu : menuList) { Integer id = menu.getId(); menuMap.put(id,menu); } // 5.再次遍历menuList查找根节点,组装父子节点 for (Menu menu : menuList) { // 6.获取当前menu对象的pid属性值 Integer pid = menu.getPid(); // 7.如果pid为null,判定为根节点 if(pid == null){ root = menu; // 8.如果当前节点是根节点,那么肯定没有父节点,不必继续执行 continue; } // 9.如果pid不为null,说明当前节点有父节点,那么可以根据pid到menuMap中查找对应的Menu对象 Menu father = menuMap.get(pid); // 10.将当前节点存入父节点的children集合 father.getChildren().add(menu); } // 11.经过上面的运算,根节点包含了整个树形结构,返回根节点就是返回整个树 return ResultEntity.successWithData(root); }
2.1.5代码:跳转页面
菜单维护
2.1.6引入zTree环境
2.1.7 代码:页面上使用 zTree 初步显示树形结构(假数据)
页面效果:
2.1.8 代码:在页面上使用真实数据显示树形结构
2.1.9 代码:修改默认图标为真实图标代码:修改默认图标为真实图标
menu-page.html中:
// 2.创建 JSON 对象用于存储对 zTree 所做的设置
var setting = {
"view":{
// 每生成一个节点都会调用一下这个函数
"addDiyDom": myAddDiyDom
}
};
my-menu.js中:
// 修改默认的图标
function myAddDiyDom(treeId, treeNode) {
// treeId是整个树形结构附着的ul标签的id:treeDemo
console.log("treeId="+treeId);
// 当前树形节点的全部的数据,包括从后端查询得到的 Menu对象的全部属性
console.log("treeNode="+treeNode);
// zTree 生成 id 的规则
// 例子:treeDemo_7_ico
// 解析:ul标签的id_当前节点的序号_功能
// 提示:"ul标签的id_当前节点的序号"部分可以通过访问 treeNode 的 tId 属性得到
// 根据 id 的生成规则拼接出来 span 标签的 id
var spanId = treeNode.tId + "_ico";
// 根据控制图标的span标签的id找到这个span标签
// 删除旧的class
// 添加新的class
$("#"+spanId).removeClass().addClass(treeNode.icon);
}



