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 相关文章推荐
PHP 程序员也要学会使用“异常”
Jun 16 PHP
用C/C++扩展你的PHP 为你的php增加功能
Sep 06 PHP
基于MySQL到MongoDB简易对照表的详解
Jun 03 PHP
PHP判断远程图片是否存在的几种方法
May 04 PHP
CodeIgniter输出中文乱码的两种解决办法
Jun 12 PHP
php的sso单点登录实现方法
Jan 08 PHP
PHP排序算法类实例
Jun 17 PHP
PHP中读取文件的几个方法总结(推荐)
Jun 03 PHP
PHP在linux上执行外部命令的方法
Feb 06 PHP
PHP实现批量清空删除指定文件夹所有内容的方法
May 30 PHP
thinkphp5.0自定义验证规则使用方法
Nov 16 PHP
thinkphp5框架API token身份验证功能示例
May 21 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
php利用事务处理转账问题
2015/04/22 PHP
typecho插件编写教程(一):Hello World
2015/05/28 PHP
PHP实现在线阅读PDF文件的方法
2015/06/17 PHP
详细解读PHP的Yii框架中登陆功能的实现
2015/08/21 PHP
PHP常用的三种设计模式
2017/02/17 PHP
PHP实现向关联数组指定的Key之前插入元素的方法
2017/06/06 PHP
TP3.2批量上传文件或图片 同名冲突问题的解决方法
2017/08/01 PHP
PHP删除字符串中非字母数字字符方法总结
2019/01/20 PHP
关于js内存泄露的一个好例子
2013/12/09 Javascript
javascript 分号总结及详细介绍
2016/09/24 Javascript
JavaScript中数组的各种操作的总结(必看篇)
2017/02/13 Javascript
canvas绘制多边形
2017/02/24 Javascript
vue实现简单的MVVM框架
2018/08/05 Javascript
vue 微信分享回调iOS和安卓回调出现错误的解决
2020/09/07 Javascript
微信小程序实现单个或多个倒计时功能
2020/11/01 Javascript
[02:27]《DAC最前线》之附加赛征程
2015/01/29 DOTA
[32:26]EG vs IG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python获取当前函数名称方法实例分享
2018/01/18 Python
django如何实现视图重定向
2019/07/24 Python
详解python环境安装selenium和手动下载安装selenium的方法
2020/03/17 Python
keras自动编码器实现系列之卷积自动编码器操作
2020/07/03 Python
Python selenium实现断言3种方法解析
2020/09/08 Python
Python hashlib和hmac模块使用方法解析
2020/12/08 Python
印尼旅游网站:via
2017/11/12 全球购物
意大利奢侈品零售商:ilDuomo Novara
2019/09/11 全球购物
毕业生造价工程师求职信
2013/10/17 职场文书
应届大学生求职信
2013/12/01 职场文书
个人简历中自我评价
2014/02/11 职场文书
学习全国两会精神心得体会范文
2014/03/17 职场文书
新农村建设典型材料
2014/05/31 职场文书
质量在我心中演讲稿
2014/09/02 职场文书
2014乡镇党政班子四风问题思想汇报
2014/09/14 职场文书
人事专员岗位职责
2015/02/03 职场文书
某药房的新员工入职告知书!
2019/07/15 职场文书
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android
德劲DE1102数字调谐收音机机评
2022/04/07 无线电