1. 程式人生 > >laravel baum巢狀集合模型簡單操作

laravel baum巢狀集合模型簡單操作

在Laravel中使用baum巢狀集合模型可以快速實現地區的新增和修改等無限極樹狀層級結構,比一般的遞迴效率要高出很多。

首先放上Baum的在GitHub的官網文件,不過是英文的。etrepat/baum

這篇部落格通過用Baum新增中國的省級、市級等關聯的地區來講一下如何簡單操作Baum。

1.安裝

composer require "baum/baum:~1.1"

2.配置

    在config/app.php檔案中

     修改providers陣列:

      新增: Baum\Providers\BaumServiceProvider::class

     修改aliases陣列:

      新增: 'Baum' => Baum\Providers\BaumServiceProvider::class

3.建立migration

    安裝到已存在的資料模型上:

    php artisan baum:install MODEL

    然後執行:

    php artisan migrate

4.模型設定:

  資料庫設定:

+----+----------+-----------+------+------+-------+---------------------+---------------------+

| id | name     | parent_id | lft  | rgt  | depth | created_at          | updated_at          |

+----+----------+-----------+------+------+-------+---------------------+---------------------+

|  1 | China    |      NULL |    1 |   10 |     0 | 2017-05-27 08:36:40 | 2017-05-27 08:36:40 |

|  2 | Zhejiang |         1 |    2 |    7 |     1 | 2017-05-27 08:36:40 | 2017-05-27 08:36:40 |

|  3 | Ningbo   |         2 |    3 |    4 |     2 | 2017-05-27 08:36:40 | 2017-05-27 08:36:40 |

|  4 | Huzhou   |         2 |    5 |    6 |     2 | 2017-05-27 08:36:40 | 2017-05-27 08:36:40 |

|  5 | Jiangsu  |         1 |    8 |    9 |     1 | 2017-05-27 08:36:40 | 2017-05-27 08:36:40 |

+----+----------+-----------+------+------+-------+---------------------+---------------------+

  模型:
<?php

namespace App;
use Baum\Node;

class Area extends Node
{
    protected $table = 'tb_area';

    // 'parent_id' column name
    protected $parentColumn = 'parent_id';
    // 'lft' column name
    protected $leftColumn = 'lft';
    // 'rgt' column name
    protected $rightColumn = 'rgt';
    // 'depth' column name
    protected $depthColumn = 'depth';

    protected $fillable = ['name'];
}

5.簡單操作

<?php

namespace App\Http\Controllers;
use App\Area;

class AreaController extends Controller
{

    public function __construct(){}

    //插入方法1
    public function insertArea1() {
        //建立根節點
        $root = Area::create(['name' => 'China']);

        // 建立子節點
        $zhejiang = $root->children()->create(['name' => 'Zhejiang']);
        //方法2
        $jiangsu = Area::create(['name' => 'Jiangsu']);
        $jiangsu->makeChildOf($root);

        //子節點的子節點
        $ningbo = Area::create(['name' => 'Ningbo']);
        $ningbo->makeChildOf($zhejiang);
    }

    //批量插入
    public function insertArea2() {
        //批量構建
        $areaTree = [
            ['name' => 'China',
                'children' => [
                    ['name' => 'Zhejiang',
                        'children' => [
                             ['name' => 'Ningbo'],
                             ['name' => 'Huzhou']
                        ]],
                    ['name' => 'Jiangsu']
            ]],
        ];
        Area::buildTree($areaTree); // => true
    }

    //輸出所有
    public function selectArea1() {
        $node = Area::where('name', '=', 'China')->first();

        foreach($node->getDescendantsAndSelf() as $descendant) {
            echo $descendant->name."<br>";
        }
    }

    //輸出所有2 (帶格式)
    public function selectArea2() {
        $node = Area::where('name', '=', 'China')->first();
        echo $node->name."<br>";
        foreach($node->getImmediateDescendants() as $descendant) {
            echo "  ".$descendant->name."<br>";
            foreach($descendant->getImmediateDescendants() as $descendant2) {
                echo "    ".$descendant2->name."<br>";
            }
        }
    }


    //刪除其中一條,並重組
    public function deleteArea() {
        $node = Area::where('name', '=', 'Ningbo')->delete();
        Area::rebuild(true);
    }


    //修改節點
    public function moveNode() {
        $areaTree = [
            ['name' => 'China',
                'children' => [
                    ['name' => 'Zhejiang',
                        'children' => [
                            ['name' => 'Ningbo'],
                            ['name' => 'Huzhou'],
                            ['name' => 'Fujian']    //這裡需要修改
                        ]],
                    ['name' => 'Jiangsu']
                ]],
        ];
        Area::buildTree($areaTree);

        $zhejiang = Area::where('name', '=', 'Zhejiang')->first();
        $fujian = Area::where('name','=', 'Fujian')->first();
        $fujian->moveToLeftOf($zhejiang);   //修改節點
    }
}