说明
在之前的文章:使用左右值树形数据结构实现树形菜单 中记录了如何使用左右值增删改查节点,本次将记录一下如何移动节点,语言使用JAVA + MYSQL实现。
总体思路
移动节点的大致思路是记录移动节点和目标节点之间的左右值以及其子节点的左右值,移动节点及其子节点左右值和目标节点及其子节点的左右值相互加减。
举例
节点A的左右值是LEFT=1,RIGHT=2,节点B的左右值是LEFT=5,RIGHT=6,现在要将节点A移动到节点B前面,那么它的移动范围就是RIGHT - LEFT + 1,即:2 - 1 +1 = 2,也就是说节点A左右值+2,左右值小于节点B的左右值-2 。
结果:节点A的LEFT = 3 ,RIGHT = 4,节点B前面的节点左右值减了2变成了LEFT=1,RIGHT=2,相当于和节点A换了个位置,如此来达到移动节点的目的
后续的移动到节点B后面、移动到节点B作为其子节点思路相同。
更新
2021-6-22 更新
修复了BUG,最新代码请关注: https://github.com/reinershir/lui-auth 以下代码摘抄自菜单管理功能
代码示例
移动节点到目标节点的前面
将要移动的节点移动动目标节点的前面作为其兄弟节点,为防止在移动节点过程中左右值被修改,需要锁定表,代码示例如下 :
1 |
|
示例代码以移动菜单为例,LEFT_VALUE,RIGHT_VALUE分别对应左值和右值
lockTables(),mysql锁表代码:
1 | jdbcTemplate.update("LOCK TABLES "+tableName+" WRITE") |
unlockTable() 手动解除锁表:
1 | jdbcTemplate.update("UNLOCK TABLES "); |
之所以要锁表是因为在修改左右值过程中不能有其它事务修改数据,否则会造成左右值错乱,整张表的数据都坏掉,所以这种数据结构有好有坏,要根据场景来使用。
移动节点到目标节点后面
此代码还可以进一步优化,目前有点冗余
1 |
|
移动节点到目标节点的子节点最后一位
移到节点到目标节点的下面,作为其子节点,并排在其子节点的最后一位,被移动节点的子节点也会跟着一并移动,代码示例:
1 | /** |
附加说明
表字段对应上一章LEFT_VALUE对应L,RIGHT_VALUE对应R,其余字段名字相同
- 本文作者: reiner
- 本文链接: https://reiner.host/posts/cfc5b0c5.html
- 版权声明: 转载请注明出处,并附上原文链接