摘要:優雅的樹形數據結構管理包基于模式設計歡迎不吝優雅的樹形數據設計模式數據和結構分表操作數據不影響結構一個操作簡單無需修改表兼容舊數據完善的樹操作方法支持生成樹形數據支持多棵樹并存多個根支持節點樹修復支持軟刪除依賴關于將樹中每個節點與其后代節點
About
優雅的樹形數據結構管理包,基于Closure Table模式設計.
github 歡迎不吝Star
Features優雅的樹形數據設計模式
數據和結構分表,操作數據不影響結構
一個Eloquent Trait操作簡單
無需修改表,兼容舊數據
完善的樹操作方法
支持生成樹形數據
支持多棵樹并存(多個根)
支持節點/樹修復
支持軟刪除
依賴php > 5.6.0
laravel > 5.1.0
關于Closure TableClosure table is a simple and elegant way of storing and querying hierarchical data in any RDBMS. By hierarchical data we mean a set of data that has some parent – child relationship among them. We use the word ‘tree’ instead of hierarchies commonly. As an example we may take the relationships between geographic locations like ‘Countries’, ‘States/ Province’, ‘Districts/ Cities’ etc.
Closure Table將樹中每個節點與其后代節點的關系都存儲了下來,
這將需要一個存儲相互關系的表name_closure.
部門表:
id | name |
---|---|
1 | 總經理 |
2 | 副總經理 |
3 | 行政主管 |
4 | 文秘 |
一個基本的closure表包含ancestor,descendant,distance3個字段,如:
ancestor | descendant | distance |
---|---|---|
1 | 1 | 0 |
1 | 2 | 1 |
1 | 3 | 2 |
1 | 4 | 3 |
2 | 2 | 0 |
2 | 3 | 1 |
2 | 4 | 2 |
3 | 3 | 0 |
3 | 4 | 1 |
4 | 4 | 0 |
這個表記錄了每個部門之間的關系,并且還記錄了一條自身的關聯.
使用ClosureTable提供了大量方法操作樹.
影響樹結構的方法makeRoot(); // 創建一個子級節點,return new model $menu->createChild($attributes); // 創建一個新的菜單,此時該菜單無任何關聯,return model $child = Menu::create($attributes); // 將一個已存在的菜單添加到子級,$child可為模型實例、模型實例集合或id、包含id的數組,return bool $menu->addChild($child); $menu->addChild(12); $menu->addChild("12"); $menu->addChild([3, 4, 5]); // 移動到$parent的下級,后代也將隨之移動,$parent可為模型實例或id,return bool $menu->moveTo($parent); $menu->moveTo(2); $menu->moveTo("2"); // 同moveTo() $menu->addTo($parent); // 添加一個或多個同級節點,$siblings的后代也將隨之移動,$siblings可為模型實例集合或id、包含id的數組,return bool $menu->addSibling($siblings); $menu->addSibling(2); $menu->addSibling("2"); $menu->addSibling([2,3,4]); // 新建一個同級節點,return new model $menu->createSibling($attributes); // 建立一個自身的關聯,return bool $menu->attachSelf(); // 解除自身的所有關聯,并且解除后代的所有關聯(這個操作不保留子樹,將使自己和所有后代都成孤立狀態),return bool $menu->detachSelf();獲取數據的方法
getDescendants(); // 獲取所有后代,包括自己,return model collection $menu->getDescendantsAndSelf(); // 獲取所有祖先,return model collection $menu->getAncestors(); // 獲取所有祖先,包括自己,return model collection $menu->getAncestorsAndSelf(); // 獲取所有兒女(直接下級),return model collection $menu->getChildren(); // 獲取父輩(直接上級),return model $menu->getParent(); // 獲取祖先(根),return model $menu->getRoot(); // 獲取所有兄弟姐妹,return model collection $menu->getSiblings(); //獲取所有兄弟姐妹包括自己,return model collection $menu->getSiblingsAndSelf(); // 獲取所有孤立節點 Menu::getIsolated(); Menu::isolated()->where("id", ">", 5)->get(); // 獲取所有根 Menu::getRoots();
以上get...()方法都包含一個query構造器,如getDescendants()對應有一個queryDescendants,這使得你可以在查詢中加入條件查詢或排序
你可以這樣使用$menu->queryDescendants()->where("id", ">", 5)->orderBy("sort","desc")->get();
getRoot(),getParent(),getRoots(),getIsolated()4個方法沒有query構造器
如果你想獲取只包含單個或多個列的結果可以在get...()方法里傳入參數,如:$menu->getAncestors(["id","name"]);
由于數據庫不需要parent_id列,如果你想在結果中顯示包含此列的內容可以在構造器后加入withParent(),
如:$menu->queryDescendantsAndSelf()->withParent()->get().
默認列名為parent,如果你想自定義這個列名在model里定義protected $parentColunm = "parent_id"
提供多種方法生成樹形數據,可從任意節點生成樹
getTree(); // 當前節點作為根生成樹,以sort字段排序,return tree $menu->getTree(["sortColumn", "desc"]); // 從根節點生成樹,return tree $menu->getRoot()->getTree(); //旁樹,不包含自己和下級,return tree $menu->getBesideTree();
生成的樹如下:
[ "id" => 3, "name" => "node3", "children" => [ [ "id" => 4, "name" => "node4" ], [ "id" => 5, "name" => "node5" "children" => [ [ "id" => 6, "name" => "node6" ] ] ] ] ]
生成的樹的children鍵默認為children,如果你想自定義可以作為第2個參數傳入,如:
$menu->getTree(["sortColumn", "desc"], "son");
如果你想獲取只包含單個或多個列的結果可以作為第3個參數傳入,如:
$menu->getTree(["sortColumn", "desc"], "son", ["id", "name"]);
你的表里可能包含多棵樹,如果你想一一獲取他們可以這樣做:
getTree(); } $data = $mutiTree;判斷
isRoot(); // 是否葉子節點 $menu->isLeaf(); // 是否孤立節點 $menu->isIsolated(); // 是否有上級 $menu->hasAncestors(); // 是否有下級 $menu->hasDescendants(); // 是否有孩子(直接下級) $menu->hasChildren(); // 是否有直接上級 $menu->hasParent(); // 是否$descendant的上級 $menu->isAncestorOf($descendant); // 是否$ancestor的下級 $menu->isDescendantOf($ancestor); // 是否$parent的直接下級 $menu->isChildOf($parent); // 是否$child的直接上級 $menu->isParentOf($child); // 是否$sibling的同級(同一個上級) $menu->isSiblingOf($sibling); // 如果$beside不是自己也不是自己的后代返回true $menu->isBesideOf($beside);數據維護
perfectNode(); // 修復樹關聯,注意:這將循環整顆樹調用perfectNode(),如果你的樹很龐大將耗費大量資源,請慎用 $menu->perfectTree();安裝
$ composer requrie jiaxincui/closure-table
建立樹需要新建一個closure表如:menu_closure
unsignedInteger("ancestor"); $table->unsignedInteger("descendant"); $table->unsignedTinyInteger("distance"); $table->primary(["ancestor", "descendant"]); });
在model里使用JiaxincuiClosureTableTraitsClosureTableTrait.
如果你想自定義表名和字段,可在model里定義以下屬性:$closureTable,$ancestorColumn,$descendantColumn,$distanceColumn.
如果你想自定義生成的樹形數據里parent字段,在model里定義屬性$parentColumn.
如下示例:
接下來,你就可以自由的使用ClosureTable帶來的所有功能了.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26077.html
摘要:查找保存下載用搭建自己的緩存倉庫權限管理的好選擇基于封裝的后臺管理系統,支持手機和端訪問支付寶風格的驗證器后臺系統微信接口的部署腳本開發的博客系統百度推送自動記錄用戶行為擴展一個項目管理系統根據生成對應導航的狀態 1.debug https://github.com/barryvdh/l... showImg(https://segmentfault.com/img/bVmhWL); ...
摘要:版微信第三方登陸包括微信微博等等,查看支持列表擴展好用的圖片處理,也方便使用百度版百度版支付集合,包含支付寶等支付寶在的封裝各國語言包,包含簡體中文生成二維碼工具,親測好用未完大家可以向我推薦,直接在本文下留言即可。 Laravel不權威導航 Hi 這里是Roy整理的Laravel相關索引,希望能幫到大家showImg(http://static.segmentfault.com/bu...
摘要:開源的論壇網站開源的論壇源代碼接口管理接口環境下環境一鍵安裝軟件二前端資源中國淘寶鏡像在國內,由于墻的原因,安裝包速度很慢,所以,這里建議使用淘寶提供的鏡像安裝前端資源。 為者常成,行者常至。 一、PHP資料 1、V2EX way to explore 分享和探索的地方2、Laravel China 中國最大的 Laravel 和 PHP 開發者社區3、Composer使用方法4、Pa...
摘要:開源的論壇網站開源的論壇源代碼接口管理接口環境下環境一鍵安裝軟件二前端資源中國淘寶鏡像在國內,由于墻的原因,安裝包速度很慢,所以,這里建議使用淘寶提供的鏡像安裝前端資源。 為者常成,行者常至。 一、PHP資料 1、V2EX way to explore 分享和探索的地方2、Laravel China 中國最大的 Laravel 和 PHP 開發者社區3、Composer使用方法4、Pa...
閱讀 2100·2023-04-26 00:09
閱讀 3121·2021-09-26 10:12
閱讀 3490·2019-08-30 15:44
閱讀 2866·2019-08-30 13:47
閱讀 927·2019-08-23 17:56
閱讀 3230·2019-08-23 15:31
閱讀 480·2019-08-23 13:47
閱讀 2516·2019-08-23 11:56