注意適用場景:僅需要獲取到某個記錄對應的數據,不適用於需要進行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();