查询树形节点 Web 案例
创建数据库表
DROP TABLE IF EXISTS `sys_dept`;
CREATE TABLE `sys_dept` (
`dept_id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent_id` bigint(20) NULL DEFAULT NULL COMMENT '上级部门ID,一级部门为0',
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '部门名称',
`order_num` int(11) NULL DEFAULT NULL COMMENT '排序',
`del_flag` tinyint(4) NULL DEFAULT 0 COMMENT '是否删除 -1:已删除 0:正常',
PRIMARY KEY (`dept_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '部门管理' ROW_FORMAT = Dynamic;
INSERT INTO `sys_dept` VALUES (1, 0, '总集团', 0, 0);
INSERT INTO `sys_dept` VALUES (2, 1, '北京分公司', 1, 0);
INSERT INTO `sys_dept` VALUES (3, 1, '上海分公司', 2, 0);
INSERT INTO `sys_dept` VALUES (4, 3, '技术部', 0, 0);
INSERT INTO `sys_dept` VALUES (5, 3, '销售部', 1, 0);
INSERT INTO `sys_dept` VALUES (6, 2, '其他部', 0, 0);
INSERT INTO `sys_dept` VALUES (7, 4, '技术三级菜单', 0, 0);
INSERT INTO `sys_dept` VALUES (8, 5, '销售三级菜单', 0, 0);
创建实体类
/**
* 部门Tree结构
*/
@TableName("sys_dept")
public class DeptEmtity implements Serializable {
/**
* 部门id
*/
@TableId(value="dept_id",type= IdType.AUTO)
private Integer deptId;
/**
* 父Id
*/
private Integer parentId;
/**
* 部门名称
*/
private String name;
/**
* 排序编号
*/
private String orderNum;
/**
* 删除标识
*/
private String delFlag;
/**
* 子节点
*/
private List<DeptEmtity> treeNode;
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getOrderNum() {
return orderNum;
}
public void setOrderNum(String orderNum) {
this.orderNum = orderNum;
}
public String getDelFlag() {
return delFlag;
}
public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
}
public List<DeptEmtity> getTreeNode() {
return treeNode;
}
public void setTreeNode(List<DeptEmtity> treeNode) {
this.treeNode = treeNode;
}
}
重要的还是看 collection 在 xml 的映射实现,NodeMapper.xml 代码如下:
<mapper namespace="com.example.demo.dao.UserDao">
<resultMap id="BaseTreeResultMap" type="com.example.demo.entity.DeptEmtity">
<result column="dept_id" property="deptId"/>
<result column="parent_id" property="parentId"/>
<result column="name" property="name"/>
<result column="order_num" property="orderNum"/>
<collection column="dept_id" property="treeNode" javaType="java.util.ArrayList"
ofType="com.example.demo.entity.DeptEmtity" select="getNextNodeTree"/>
</resultMap>
<resultMap id="NextTreeResultMap" type="com.example.demo.entity.DeptEmtity">
<result column="dept_id" property="deptId"/>
<result column="parent_id" property="parentId"/>
<result column="name" property="name"/>
<result column="order_num" property="orderNum"/>
<collection column="dept_id" property="treeNode" javaType="java.util.ArrayList"
ofType="com.example.demo.entity.DeptEmtity" select="getNextNodeTree"/>
</resultMap>
<select id="getNextNodeTree" resultMap="NextTreeResultMap">
SELECT
*
FROM sys_dept
WHERE parent_id = #{deptId}
</select>
<select id="getNodeTree" resultMap="BaseTreeResultMap">
SELECT
*
FROM sys_dept
WHERE parent_id = 0
</select>
</mapper>
parent_id = 0 代表顶级节点。然后通过 collection 节点继续调用 getNextNodeTree 方法进行循环调用。
在 dao 层,我们只调用 getNodeTree 方法就可以实现了:
@Mapper
public interface UserDao {
List<DeptEmtity> getNodeTree();
}
以下是关键的知识点:
- column 代表会拿父节点 dept_id ,作为参数获取 next 对象
- treeNode 对象是个列表,其实可以省略不写
- ofType 用来区分 JavaBean 属性类型和集合包含的类型
- select 是用来执行循环哪个 SQL
工程演示后的结果如图所示:
本文参考:BYSocket泥瓦匠 文章。大家也可以关注他的公众号。