可拖拽树形数据服务器端的一种实现
介绍
树形结构的数据常用于部门管理等有层次结构的场景。目前对于树形结构的UI操作已经有相当多的库了,如ztree、jsTree;一些出名的组件库也都内置的相应的组件,如element-ui。但就目前关于树拖拽操作的后台逻辑实现却少有人提及,特别是在像mysql这种关系型数据下的实现。正好公司前些日子需要这个功能,形成了一个实现方案,整理后放出。
观前提示
- 非Java警告:案例使用kotlin+springboot写成
- 非传统ORM警告:ORM框架选用ktorm。别问,问就是开心就好
不了解kotlin基本语法可能看着会有点恼火,毕竟它的糖实在是太多了。查询使用的语句比较简单,不了解ktorm,应该影响不大。
案例代码:gitee
业务需求
部分新用户一次性导入大量的部门信息,需要调整部门间层级关系。原有的编辑框操作繁琐也不直观,所以想能不能通过拖拽实现层级关系调整。
经过调查,用户导入的部门数量最大在四位数的量级,部门层级最多在5级之内。由于有权限的设定,所以也有查询某部门下所有子部门的需求。
总的来说,拖拽功能是较低频的操作,而查询某部门下所有子部门是高频操作。因此功能设计的总体目标也就出来:拖拽可以慢点,查询需要快。
数据库设计
在关系型数据存储树形结构通常考虑四种方法:
- 邻接表(Adjacency List):保存pId值
- 路径枚举(Path Enumerations):记录此节点经过的路径
- 嵌套表(Nested Sets):比较麻烦,记录左值、右值,计算方式有点麻烦
- 闭包表(Closure Table):用另一张表辅助记录
此次采用前两方式混合。即