laravel設置ORM關聯關係(分表相關)

注意適用場景:僅需要獲取到某個記錄對應的數據,不適用於需要進行with內部進行where判斷的場景,其他分表場景建議使用數據庫中間件處理

最下面有使用普通table做連表的寫法(能用,但是比較醜)

示例:tests與records表1對多關係

1:records模型如下

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Record extends Model
{
    protected $suffix = null;

    /**
     * @param $suffix
     * 設置對象表名
     */
    public function setSuffix($suffix)
    {
        $this->suffix = $suffix;
        if ($suffix !== null) {
            $this->table = 'records_' . $suffix;
        }
    }

    /**
     * @return string
     * 獲取對象表名
     */
    public function getTable(){
        return $this->table;
    }

    /**
     * @param $suffix
     * @return mixed
     * 設置表
     */
    public static function suffix($suffix)
    {
        $instance = new static;
        $instance->setSuffix($suffix);

        return $instance->newQuery();
    }

    /**
     * @param array $attributes
     * @param bool $exists
     * @return static
     * 自定義模型並返回
     */
    public function newInstance($attributes = [], $exists = false)
    {
        $model = parent::newInstance($attributes, $exists);
        $model->setSuffix($this->suffix);

        return $model;
    }

    /**
     * @param $testId
     * @return mixed
     * 通過外鍵獲取關聯數據
     */
    public static function lists ($testId)
    {
        $suffix = $testId;
        /*
        * 例如 $sufiix = 1; 我要要獲取的就是:records_1的模型實例
        */
        return self::suffix($suffix)->where('test_id', $testId)->get();
    }
}

2:test模型如下

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Test extends Model
{
    //指定表名
    protected $table = 'tests';

    //指定主鍵
    protected $primaryKey = 'id';

    //時間戳自動維護
    // public $timestamps = true;

    //指定允許批批量賦值字段
    protected $fillable = ['name'];

    /**
     * @return HasMany
     * 手動設置一對多關係
     */
    public function records ()
    {
        $instance = new Record();
        $instance->setSuffix($this->id);

        $foreignKey = $instance->getTable() . '.' . $this->getForeignKey();
        $localKey = $this->getKeyName();

        return new HasMany($instance->newQuery(), $this, $foreignKey, $localKey);
    }
}

3:數據獲取方式如下(兩種方式都可以獲取到關聯的數據)

Route::post('relate', function(\App\Test $test){
    // return \App\Record::lists(2);
    return \App\Test::find(1)->records;
});

4:普通連表寫法

DB::table('tests')
        ->select('tests.*','t.id as tid','t.name as tname')
        ->join(
            DB::raw('( (SELECT records_1.* FROM records_1) UNION (SELECT records_2.* FROM records_2) UNION (SELECT records_3.* FROM records_3) UNION (SELECT records_4.* FROM records_4) ) as t'),
            function($join){
                $join->on('tests.id', '=', 't.test_id');
            }
        )->get();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章