基于ssm与maven,使用easyui--tree生成类似部门管理树形结构图

基于ssm与maven,使用easyui--tree生成类似部门管理树形结构图

本文主要记录自己在实际开发中,遇到的一个问题:需要数据库中读取部门数据,并生成部门管理树形结构图,对部门进行操作,显示效果如下图所示:

基于ssm与maven,使用easyui--tree生成类似部门管理树形结构图

由于涉及到公司商业机密,因此在此自己将这个模块单独提炼出来并做了一些修改,并只贴出主要代码。

一、前期说明及准备:

1.后台是基于ssm框架(Spring MVC+Spring+Mybatis);

2.使用mysql数据库;

3.前端使用easyUI+freeMark。

4.项目使用maven构建,Eclipse开发;

5.dao、model、mapper使用mybatis-generator自动生成

6.创建一个名为“treedemo”的数据库及名为“dept”的表,sql语句如下:

[sql] view plain copy
  1. CREATE DATABASE treedemo;  
  2. USE treedemo;  
  3.   
  4. /*  
  5. Navicat MySQL Data Transfer  
  6.   
  7. Source Server         : mysql  
  8. Source Server Version : 50022  
  9. Source Host           : localhost:3306  
  10. Source Database       : treedemo  
  11.   
  12. Target Server Type    : MYSQL  
  13. Target Server Version : 50022  
  14. File Encoding         : 65001  
  15. */  
  16.   
  17. SET FOREIGN_KEY_CHECKS=0;  
  18.   
  19. -- ----------------------------  
  20. -- Table structure for dept  
  21. -- ----------------------------  
  22. DROP TABLE IF EXISTS `dept`;  
  23. CREATE TABLE `dept` (  
  24.   `id` varchar(32) NOT NULL,  
  25.   `pid` varchar(32) NOT NULL,  
  26.   `namevarchar(50) NOT NULL,  
  27.   `type` varchar(32) ,  
  28.   PRIMARY KEY  (`id`)  
  29. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  30.   
  31. -- ----------------------------  
  32. -- Records of dept  
  33. -- ----------------------------  
  34. INSERT INTO `dept` VALUES ('0a22ff1186f24a6b9189ae0bccc37528''9ebd264055aa4f5b9112db58c338e94e''广告部1','dept');  
  35. INSERT INTO `dept` VALUES ('2c9153620f6344bda08ed1b238a4cdf0''e99e1e819fce4dac8054d8c42e4854ab''业务部','dept');  
  36. INSERT INTO `dept` VALUES ('2f83c97cb5464890bba8291b51bd61a8''e99e1e819fce4dac8054d8c42e4854ab''研发部','dept');  
  37. INSERT INTO `dept` VALUES ('33f0fbc0243743cfa615714b1764fcf7''da7b002944dd41d0bf7c00120b94bb48''财务部','dept');  
  38. INSERT INTO `dept` VALUES ('3b70590f02e1486a967b2eb3463d024c''779df9d28040485781768a08ead27567''活动部','dept');  
  39. INSERT INTO `dept` VALUES ('779df9d28040485781768a08ead27567''e99e1e819fce4dac8054d8c42e4854ab''企划部','dept');  
  40. INSERT INTO `dept` VALUES ('7ac8139930fb4a5fb4fd5412e2aa87bf''e99e1e819fce4dac8054d8c42e4854ab''销售部','dept');  
  41. INSERT INTO `dept` VALUES ('9ebd264055aa4f5b9112db58c338e94e''df6253b3095c4d2c8083ef9cd4074b40''广告部','dept');  
  42. INSERT INTO `dept` VALUES ('b7091fb6a38149079d07911d4b5a9537''9ebd264055aa4f5b9112db58c338e94e''广告部2','dept');  
  43. INSERT INTO `dept` VALUES ('da7b002944dd41d0bf7c00120b94bb48''e99e1e819fce4dac8054d8c42e4854ab''运营部','dept');  
  44. INSERT INTO `dept` VALUES ('df6253b3095c4d2c8083ef9cd4074b40''33f0fbc0243743cfa615714b1764fcf7''策划部','dept');  
  45. INSERT INTO `dept` VALUES ('e99e1e819fce4dac8054d8c42e4854ab''00000000000000000000000000000000''示例单位','unit');  

二、后台代码

后台代码结构:

基于ssm与maven,使用easyui--tree生成类似部门管理树形结构图

1.Dept.java

      与数据库中的dept表对应,其如下代码:

[java] view plain copy
  1. package com.beauxie.model;  
  2.   
  3. public class Dept {  
  4.     /** 
  5.      * This field was generated by MyBatis Generator. 
  6.      * This field corresponds to the database column dept.id 
  7.      * 
  8.      * @mbggenerated 
  9.      */  
  10.     private String id;  
  11.   
  12.     /** 
  13.      * This field was generated by MyBatis Generator. 
  14.      * This field corresponds to the database column dept.pid 
  15.      * 
  16.      * @mbggenerated 
  17.      */  
  18.     private String pid;  
  19.   
  20.     /** 
  21.      * This field was generated by MyBatis Generator. 
  22.      * This field corresponds to the database column dept.name 
  23.      * 
  24.      * @mbggenerated 
  25.      */  
  26.     private String name;  
  27.   
  28.     /** 
  29.      * This field was generated by MyBatis Generator. 
  30.      * This field corresponds to the database column dept.type 
  31.      * 
  32.      * @mbggenerated 
  33.      */  
  34.     private String type;  
  35.   
  36.     /** 
  37.      * This method was generated by MyBatis Generator. 
  38.      * This method returns the value of the database column dept.id 
  39.      * 
  40.      * @return the value of dept.id 
  41.      * 
  42.      * @mbggenerated 
  43.      */  
  44.     public String getId() {  
  45.         return id;  
  46.     }  
  47.   
  48.     /** 
  49.      * This method was generated by MyBatis Generator. 
  50.      * This method sets the value of the database column dept.id 
  51.      * 
  52.      * @param id the value for dept.id 
  53.      * 
  54.      * @mbggenerated 
  55.      */  
  56.     public void setId(String id) {  
  57.         this.id = id == null ? null : id.trim();  
  58.     }  
  59.   
  60.     /** 
  61.      * This method was generated by MyBatis Generator. 
  62.      * This method returns the value of the database column dept.pid 
  63.      * 
  64.      * @return the value of dept.pid 
  65.      * 
  66.      * @mbggenerated 
  67.      */  
  68.     public String getPid() {  
  69.         return pid;  
  70.     }  
  71.   
  72.     /** 
  73.      * This method was generated by MyBatis Generator. 
  74.      * This method sets the value of the database column dept.pid 
  75.      * 
  76.      * @param pid the value for dept.pid 
  77.      * 
  78.      * @mbggenerated 
  79.      */  
  80.     public void setPid(String pid) {  
  81.         this.pid = pid == null ? null : pid.trim();  
  82.     }  
  83.   
  84.     /** 
  85.      * This method was generated by MyBatis Generator. 
  86.      * This method returns the value of the database column dept.name 
  87.      * 
  88.      * @return the value of dept.name 
  89.      * 
  90.      * @mbggenerated 
  91.      */  
  92.     public String getName() {  
  93.         return name;  
  94.     }  
  95.   
  96.     /** 
  97.      * This method was generated by MyBatis Generator. 
  98.      * This method sets the value of the database column dept.name 
  99.      * 
  100.      * @param name the value for dept.name 
  101.      * 
  102.      * @mbggenerated 
  103.      */  
  104.     public void setName(String name) {  
  105.         this.name = name == null ? null : name.trim();  
  106.     }  
  107.   
  108.     /** 
  109.      * This method was generated by MyBatis Generator. 
  110.      * This method returns the value of the database column dept.type 
  111.      * 
  112.      * @return the value of dept.type 
  113.      * 
  114.      * @mbggenerated 
  115.      */  
  116.     public String getType() {  
  117.         return type;  
  118.     }  
  119.   
  120.     /** 
  121.      * This method was generated by MyBatis Generator. 
  122.      * This method sets the value of the database column dept.type 
  123.      * 
  124.      * @param type the value for dept.type 
  125.      * 
  126.      * @mbggenerated 
  127.      */  
  128.     public void setType(String type) {  
  129.         this.type = type == null ? null : type.trim();  
  130.     }  
  131. }  

2.DeptMapper.xml

      主要提供一个查询方法,用以查询单位或部门:

[html] view plain copy
  1. <mapper namespace="com.beauxie.dao.DeptMapper">  
  2.     <resultMap id="BaseResultMap" type="com.beauxie.model.Dept">  
  3.         <!-- WARNING - @mbggenerated This element is automatically generated by   
  4.             MyBatis Generator, do not modify. -->  
  5.         <id column="id" property="id" jdbcType="VARCHAR" />  
  6.         <result column="pid" property="pid" jdbcType="VARCHAR" />  
  7.         <result column="name" property="name" jdbcType="VARCHAR" />  
  8.         <result column="type" property="type" jdbcType="VARCHAR" />  
  9.     </resultMap>  
  10.   
  11.   
  12.     //中间无关代码省略...  
  13.   
  14.   
  15.     <!-- 查询符合条件的记录 -->  
  16.     <select id="list" parameterType="map" resultMap="BaseResultMap">  
  17.         SELECT  
  18.         <include refid="Base_Column_List" />  
  19.         FROM  
  20.         dept  
  21.         WHERE  
  22.         type like #{type,jdbcType=VARCHAR}  
  23.         <if test="id != null">  
  24.             AND id like #{id,jdbcType=VARCHAR}  
  25.         </if>  
  26.         <if test="pid != null">  
  27.             AND pid like #{pid,jdbcType=VARCHAR}  
  28.         </if>  
  29.   
  30.     </select>  
  31.   
  32. </mapper>  

3.DeptMapper.java

与DeptMapper.xml对应,代码如下:
[java] view plain copy
  1. package com.beauxie.dao;  
  2.   
  3. import java.util.List;  
  4. import java.util.Map;  
  5.   
  6. import com.beauxie.model.Dept;  
  7.   
  8. public interface DeptMapper {  
  9.     /** 
  10.      * This method was generated by MyBatis Generator. 
  11.      * This method corresponds to the database table dept 
  12.      * 
  13.      * @mbggenerated 
  14.      */  
  15.     int deleteByPrimaryKey(String id);  
  16.   
  17.     /** 
  18.      * This method was generated by MyBatis Generator. 
  19.      * This method corresponds to the database table dept 
  20.      * 
  21.      * @mbggenerated 
  22.      */  
  23.     int insert(Dept record);  
  24.   
  25.     /** 
  26.      * This method was generated by MyBatis Generator. 
  27.      * This method corresponds to the database table dept 
  28.      * 
  29.      * @mbggenerated 
  30.      */  
  31.     int insertSelective(Dept record);  
  32.   
  33.     /** 
  34.      * This method was generated by MyBatis Generator. 
  35.      * This method corresponds to the database table dept 
  36.      * 
  37.      * @mbggenerated 
  38.      */  
  39.     Dept selectByPrimaryKey(String id);  
  40.   
  41.     /** 
  42.      * This method was generated by MyBatis Generator. 
  43.      * This method corresponds to the database table dept 
  44.      * 
  45.      * @mbggenerated 
  46.      */  
  47.     int updateByPrimaryKeySelective(Dept record);  
  48.   
  49.     /** 
  50.      * This method was generated by MyBatis Generator. 
  51.      * This method corresponds to the database table dept 
  52.      * 
  53.      * @mbggenerated 
  54.      */  
  55.     int updateByPrimaryKey(Dept record);  
  56.       
  57.       
  58.     /** 
  59.      * @param para 
  60.      * @return List<Dept> 
  61.      */  
  62.     List<Dept> list(Map<String, Object> para);  
  63. }  

4.DeptServiceI.java

       是一个service层的接口,里面只有一个抽象方法,如下:

[java] view plain copy
  1. package com.beauxie.service;  
  2.   
  3. import com.beauxie.util.TreeModel;  
  4.   
  5. public interface DeptServiceI {  
  6.       
  7.   
  8.     /** 
  9.      * 返回所有的单位及部门的树形结构 
  10.     * @param id 部门id,即作为下一级子节点的pid 
  11.     * @param containsDept 是否包含子节点 
  12.     * @return TreeModel 
  13.     */  
  14.    TreeModel selectTree(String id, boolean containsDept);  
  15. }  

5.DeptServiceImpl.java

    该类实现了DeptServiceI接口,是构造组织树的主要代码,如下:

[java] view plain copy
  1. package com.beauxie.service.impl;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7. import javax.annotation.Resource;  
  8.   
  9. import org.springframework.stereotype.Service;  
  10. import org.springframework.util.CollectionUtils;  
  11.   
  12. import com.beauxie.dao.DeptMapper;  
  13. import com.beauxie.model.Dept;  
  14. import com.beauxie.service.DeptServiceI;  
  15. import com.beauxie.util.TreeModel;  
  16. import com.beauxie.util.TreeUtil;  
  17.   
  18.   
  19. @Service  
  20. public class DeptServiceImpl implements DeptServiceI{  
  21.       
  22.     @Resource//或者@Autowired  
  23.     private DeptMapper deptMapper;  
  24.       
  25.   
  26.     /******************************************************** 构造单位及部门树形结构 ********************************************************/  
  27.   
  28.     private List<Dept> selectChildren(String id, String type) {  
  29.         Map<String, Object> para = new HashMap<String, Object>();  
  30.         para.put("type", type);  
  31.         para.put("pid", id);  
  32.         return deptMapper.list(para);  
  33.     }  
  34.   
  35.     public TreeModel selectTree(String id, boolean containsDept) {  
  36.         TreeModel tm = new TreeModel();  
  37.           
  38.         //在此只保留部门或单位的id及name属性,可拓展  
  39.         String[] s = new String[] { "getId""getName" };  
  40.         String type = containsDept ? "%" : "unit";  
  41.         List<Dept> li = this.selectChildren(id, type);  
  42.         this.tree(tm, li, s, containsDept);  
  43.         return tm;  
  44.     }  
  45.   
  46.     // 构造组织机构树数据  
  47.     private void tree(TreeModel tm, List<Dept> li, String[] s,  
  48.             boolean containsDept) {  
  49.   
  50.         if (!CollectionUtils.isEmpty(li)) {  
  51.   
  52.             for (int i = 0, l = li.size(); i < l; i++) {  
  53.                 TreeModel ntm = new TreeModel();  
  54.                 Dept dept = li.get(i);  
  55.   
  56.                 TreeUtil.copyModel(ntm, dept, s);// 复制值到TreeModel  
  57.                 tm.getChildren().add(ntm);// 添加到孩子节点列表  
  58.   
  59.                 String type = containsDept ? "%" : "unit";  
  60.                 List<Dept> list = this.selectChildren(dept.getId(), type);  
  61.                 tree(ntm, list, s, containsDept);// 递归,实现无限层级  
  62.             }  
  63.         }  
  64.     }  
  65.   
  66.     /******************************************************** end ********************************************************/  
  67.   
  68. }  

6.TreeModel.java

   自定义的树的数据模型,代码如下:

[java] view plain copy
  1. package com.beauxie.util;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. /** 
  7.  * 树的数据模型 
  8.  */  
  9. public class TreeModel {  
  10.   
  11.     private String id;  
  12.     private String text;// 名称  
  13.     private String iconCls;// 图标  
  14.     private String linkUrl;// 链接地址  
  15.       
  16.     // 状态(closed折叠、open展开)  
  17. //  private String state = "closed";  
  18.     private List<TreeModel> children;// 孩子节点集合  
  19.   
  20.     public TreeModel() {  
  21.         this.children = new ArrayList<TreeModel>();  
  22.     }  
  23.   
  24.     public String getId() {  
  25.         return id;  
  26.     }  
  27.   
  28.     public void setId(String id) {  
  29.         this.id = id;  
  30.     }  
  31.   
  32.     public String getText() {  
  33.         return text;  
  34.     }  
  35.   
  36.     public void setText(String text) {  
  37.         this.text = text;  
  38.     }  
  39.   
  40.     public String getLinkUrl() {  
  41.         return linkUrl;  
  42.     }  
  43.   
  44.     public void setLinkUrl(String linkUrl) {  
  45.         this.linkUrl = linkUrl;  
  46.     }  
  47.   
  48.     public String getIconCls() {  
  49.         return iconCls;  
  50.     }  
  51.   
  52.     public void setIconCls(String iconCls) {  
  53.         this.iconCls = iconCls;  
  54.     }  
  55.   
  56.     public List<TreeModel> getChildren() {  
  57.         return children;  
  58.     }  
  59.   
  60.     public void setChildren(List<TreeModel> children) {  
  61.         this.children = children;  
  62.     }  
  63.       
  64. }  

7.TreeUtil.java

    该类是一个工具类,用以构造树,代码如下所示:

[java] view plain copy
  1. package com.beauxie.util;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. /** 
  6.  * 树结构处理工具类 
  7.  */  
  8. public class TreeUtil {  
  9.   
  10.   
  11.     /** 
  12.      * 复制数据到树model 
  13.      * @param tm 树model 
  14.      * @param o 待复制的对象 
  15.      * @param s 变长参数,方法的名称字符串 
  16.      *          约定第1个为id,第2个为text, 
  17.      *          第3个为linkUrl,第4个为iconCls, 
  18.      *          第5个为splitNum 
  19.      */  
  20.     public static void copyModel(TreeModel tm, Object o, String... s) {  
  21.         Class<?> clazz = o.getClass();// 获取类包名  
  22.         int l = s.length;  
  23.   
  24.         try {  
  25.             if(l - 0 > 0 && s[0] != null) {  
  26.                 Method id = clazz.getMethod(s[0]);// 约定第1个为id  
  27.                 tm.setId(String.valueOf(id.invoke(o)));  
  28.             }  
  29.             if(l - 1 > 0 && s[1] != null) {  
  30.                 Method text = clazz.getMethod(s[1]);// 约定第2个为text  
  31.                 tm.setText(String.valueOf(text.invoke(o)));  
  32.             }  
  33.             if(l - 2 > 0 && s[2] != null) {  
  34.                 Method url = clazz.getMethod(s[2]);// 约定第3个为funcUrl  
  35.                 tm.setLinkUrl(String.valueOf(url.invoke(o)));  
  36.             }  
  37.             if(l - 3 > 0 && s[3] != null) {  
  38.                 Method cls = clazz.getMethod(s[3]);// 约定第4个为iconCls  
  39.                 tm.setIconCls(String.valueOf(cls.invoke(o)));  
  40.             }  
  41.         } catch (Exception e) {  
  42.             e.printStackTrace();  
  43.         }  
  44.     }  
  45. }  

8.DeptController.java

[java] view plain copy
  1. package com.beauxie.controller;  
  2.   
  3. import java.util.List;  
  4.   
  5. import javax.annotation.Resource;  
  6. import javax.servlet.http.HttpServletRequest;  
  7.   
  8. import org.springframework.stereotype.Controller;  
  9. import org.springframework.web.bind.annotation.RequestMapping;  
  10. import org.springframework.web.bind.annotation.ResponseBody;  
  11.   
  12. import com.beauxie.service.DeptServiceI;  
  13. import com.beauxie.util.TreeModel;  
  14.   
  15. @Controller  
  16. @RequestMapping("/deptController")  
  17. public class DeptController {  
  18.   
  19.     @Resource  
  20.     private DeptServiceI deptService;  
  21.   
  22.     // 表示根目录的pid  
  23.     public static final String ROOT = "00000000000000000000000000000000";  
  24.   
  25.     /** 
  26.      * 单位部门树(含部门)json 
  27.      */  
  28.     @RequestMapping("/deptTree")  
  29.     @ResponseBody  
  30.     // 返回的是JSON格式  
  31.     public List<TreeModel> deptTree(HttpServletRequest request) {  
  32.         // 默认从根节点开始  
  33.         String id = ROOT;  
  34.         TreeModel tm = deptService.selectTree(id, true);  
  35.         return tm.getChildren();  
  36.     }  
  37. }  

三、前段代码

基于ssm与maven,使用easyui--tree生成类似部门管理树形结构图

1.index.js

向后台发送数据请求,并接收、处理后台传回来的数据,代码如下:

[javascript] view plain copy
  1. var treeUrl = '/treedemo/deptController/deptTree.do';  
  2. var tree = null;//表示树  
  3.   
  4. $(function() {  
  5.     tree = $('#vl');  
  6.     initTree();//初始化树  
  7.   
  8. });  
  9.   
  10. function initTree() {  
  11.      tree.tree({  
  12.         url: treeUrl,  
  13.         animate: false,  
  14.         lines : true,  
  15.         checkbox : false,//是否显示复选框  
  16.         onClick: function(node) {  
  17.             //nodeClick(node);  
  18.         },  
  19.         onLoadSuccess: function(data) {  
  20.             alert("加载成功!");  
  21.         }  
  22.     });   
  23. }  

2.index.html

    显示树,代码如下:

[html] view plain copy
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta http-equiv="pragma" content="no-cache">  
  5. <meta http-equiv="cache-control" content="no-cache">  
  6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
  7. <title>treedemo</title>  
  8.   
  9. <link rel="stylesheet" type="text/css"  
  10.     href="js_lib/easyui/themes/default/easyui.css">  
  11. <link rel="stylesheet" type="text/css"  
  12.     href="js_lib/easyui/themes/icon.css">  
  13.   
  14. <script type="text/javascript" src="js_lib/jquery-1.8.3.min.js"></script>  
  15. <script type="text/javascript"  
  16.     src="js_lib/easyui/jquery.easyui.min.js"></script>  
  17. <script type="text/javascript"  
  18.     src="js_lib/easyui/easyui-lang-zh_CN.js"></script>  
  19. <script type="text/javascript"  
  20.     src="js/index.js"></script>  
  21.   
  22. </head>  
  23. <body>  
  24.   
  25.     <div style="width: 30%; position: absolute; top: 34px; bottom: 0;">  
  26.         <ul id="vl" data-options="region:'center',border: true"  
  27.             class="easyui-tree">  
  28.         </ul>  
  29.     </div>  
  30.   
  31. </body>  
  32. </html>  

四、总结

1.前台代码并不复杂,只是一个控件,关键是后台的逻辑代码;

2.首先自己定义了一个树的数据模型,然后再从数据库中查找出数据,通过工具方法将数据封装到树model里,默认从根节点开始查找。