注意适用场景:仅需要获取到某个记录对应的数据,不适用于需要进行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();