Laravel Eloquent分表方法并使用模型关联的实现


Posted in PHP onNovember 25, 2019

众所周知 Laravel 是 PHP 开发项目最优美的框架之一,尤其是 Eloquent 对数据库的操作提供了特别多的便利。
在实际开发中我们经常涉及到分库分表场景,那么怎样才能继续配合 Eloquent 优雅的使用 Model 模型呢,接下来给大家分享下我在实际开发中所遇到的问题。(备注:此方法来源 Stack OverFlow 原文地址找不到了,配合我们实际项目更能清晰表述)

1、假设我们有一万本书籍,每本书籍有两千章节,我们创建数据库时的表结构是书籍信息表:books;以及章节信息表:chapters,前面说到书籍越多章节数也就越多解决方案是将章节表分成十个形式为 chapters_0、chapters_1、......chapters_9 表后缀规则是书籍 ID 与 10 取余,这样所有的书籍章节会分散在这 10 个 chapters 中。

2、表建好后开始创建 model 模型,按照惯例所有的模型都将写在 App\Models 下;首先我们先创建一个类名为 Model 的模型并继承 Illuminate\Database\Eloquent\Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model as EloquentModel;

class Model extends EloquentModel
{
  protected $suffix = null;

  // 设置表后缀
  public function setSuffix($suffix)
  {
    $this->suffix = $suffix;
    if ($suffix !== null) {
      $this->table = $this->getTable() . '_' . $suffix;
    }
  }

  // 提供一个静态方法设置表后缀
  public static function suffix($suffix)
  {
    $instance = new static;
    $instance->setSuffix($suffix);

    return $instance->newQuery();
  }

  // 创建新的"chapters_{$suffix}"的模型实例并返回
  public function newInstance($attributes = [], $exists = false)
  {
    $model = parent::newInstance($attributes, $exists);
    $model->setSuffix($this->suffix);

    return $model;
  }
}

2、其他模型全都继承以上的 Model 而不是继承 Illuminate\Database\Eloquent\Model,获取某本书的章节 controller

<?php

namespace App\Http\Controllers;

use App\Models\{Book, Chapter};

class ChaptersController extends Controller
{
  public function chapter (Book $book)
  {
    // 章节列表(普通查询)
    $list = Chapter::lists($book->id);

    // 章节列表(使用模型关联)
    $list = $book->chapters()->oldest('id')->get();
  }
}

3、chapter 模型(普通查询)

<?php

namespace App\Models;

class Chapter extends Model
{
  public static function lists ($bookId)
  {
    $suffix = $bookId % 10;
    /*
    * 例如 $sufiix = 1; 我要要获取的就是:chapters_1的模型实例
    * 使用Model类中提供的静态方法创建该表的模型实例
    * 返回指定书籍的章节
    */
    return self::suffix($suffix)->where('book_id', $bookId)->get();
  }
}

3、好了,我们章节的分表模型已经完成了。那么如何使用模型关联呢?我们来看 Book 模型如何关联 Chapter

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\HasMany;

class Book extends Model
{
  public function chapters ()
  {
    /*
    * books表的id和chapters表中的book_id关联
    * 一对多关系(一本书对应多条章节)
    */
    $instance = new Chapter();
    $instance->setSuffix($this->id % 10);

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

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

到此 model 发表查询及 model 关联就完成了,如果有其他更好的方式,请大家不吝赐教。第一次发表文章,如有不对的地方希望大家多多指教!!也希望大家多多支持三水点靠木。

PHP 相关文章推荐
一个简单的自动发送邮件系统(三)
Oct 09 PHP
php error_log 函数的使用
Apr 13 PHP
基于PHP遍历数组的方法汇总分析
Jun 08 PHP
php修改NetBeans默认字体的大小
Jul 02 PHP
php自定义hash函数实例
May 05 PHP
WordPress迁移时一些常见问题的解决方法整理
Nov 24 PHP
PHP curl模拟登录带验证码的网站
Nov 30 PHP
盘点PHP和ASP.NET的10大对比!
Dec 24 PHP
PHP使用file_get_content设置头信息的方法
Feb 14 PHP
Symfony2框架学习笔记之表单用法详解
Mar 18 PHP
php cookie 详解使用实例
Nov 03 PHP
php中final关键字用法分析
Dec 07 PHP
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
Nov 25 #PHP
使用Git实现Laravel项目的自动化部署
Nov 24 #PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
Nov 24 #PHP
laravel框架中视图的基本使用方法分析
Nov 23 #PHP
laravel框架中表单请求类型和CSRF防护实例分析
Nov 23 #PHP
laravel框架中控制器的创建和使用方法分析
Nov 23 #PHP
laravel框架模型中非静态方法也能静态调用的原理分析
Nov 23 #PHP
You might like
SMARTY学习手记
2007/01/04 PHP
PHP下通过系统信号量加锁方式获取递增序列ID
2009/09/25 PHP
php生成二维码
2015/08/10 PHP
yii分页组件用法实例分析
2015/12/28 PHP
PHP实现求连续子数组最大和问题2种解决方法
2017/12/26 PHP
Laravel 框架路由原理与路由访问实例分析
2020/04/14 PHP
可以把编码转换成 gb2312编码lib.UTF8toGB2312.js
2007/08/21 Javascript
判断iframe是否加载完成的完美方法
2010/01/07 Javascript
关于document.cookie的使用javascript
2010/10/29 Javascript
javascript检查表单数据是否改变的方法
2013/07/30 Javascript
javascript 获取浏览器版本
2015/01/21 Javascript
Node.js抓取中文网页乱码问题和解决方法
2015/02/10 Javascript
深入理解JavaScript系列(37):设计模式之享元模式详解
2015/03/04 Javascript
JS+CSS实现表格高亮的方法
2015/08/05 Javascript
JavaScript实现网页加载进度条代码超简单
2015/09/21 Javascript
微信小程序 WXDropDownMenu组件详解及实例代码
2016/10/24 Javascript
JS 实现可停顿的垂直滚动实例代码
2016/11/23 Javascript
详解js的事件代理(委托)
2016/12/22 Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
2017/08/28 Javascript
在 webpack 中使用 ECharts的实例详解
2018/02/05 Javascript
详解基于Vue/React项目的移动端适配方案
2019/08/23 Javascript
pymongo为mongodb数据库添加索引的方法
2015/05/11 Python
解析Python中的生成器及其与迭代器的差异
2016/06/20 Python
python使用logging模块发送邮件代码示例
2018/01/18 Python
python实现从pdf文件中提取文本,并自动翻译的方法
2018/11/28 Python
python的常用模块之collections模块详解
2018/12/06 Python
使用python serial 获取所有的串口名称的实例
2019/07/02 Python
Python hashlib和hmac模块使用方法解析
2020/12/08 Python
详解通过HTML5 Canvas实现图片的平移及旋转变化的方法
2016/03/22 HTML / CSS
活动总结的格式
2014/05/07 职场文书
县级文明单位申报材料
2014/05/23 职场文书
乡镇消防安全责任书
2014/07/23 职场文书
授权委托书格式
2014/07/31 职场文书
先进教育工作者事迹材料
2014/12/23 职场文书
工作失误检讨书范文
2015/01/26 职场文书
2016学习雷锋精神活动倡议书
2015/04/27 职场文书