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面向对象三大特点学习(充分理解抽象、封装、继承、多态)
May 07 PHP
ThinkPHP3.1新特性之对页面压缩输出的支持
Jun 19 PHP
PHP调用wsdl文件类型的接口代码分享
Nov 19 PHP
php限制上传文件类型并保存上传文件的方法
Mar 13 PHP
php判断对象是派生自哪个类的方法
Jun 20 PHP
php比较两个字符串长度的方法
Jul 13 PHP
PHP实现合并discuz用户
Aug 05 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
Nov 14 PHP
PHP实现的基于单向链表解决约瑟夫环问题示例
Sep 30 PHP
PHP 观察者模式深入理解与应用分析
Sep 25 PHP
laravel框架实现敏感词汇过滤功能示例
Feb 15 PHP
TP5框架实现的数据库备份功能示例
Apr 05 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的拦截器实例分析
2014/11/03 PHP
PHP中array_slice函数用法实例详解
2014/11/25 PHP
Laravel中9个不经常用的小技巧汇总
2019/04/16 PHP
Yii2 queue的队列使用详解
2019/07/19 PHP
javascript实现切换td中的值
2014/12/05 Javascript
DOM节点深度克隆函数cloneNode()用法实例
2015/01/12 Javascript
JavaScript包装对象使用详解
2015/07/09 Javascript
详解JavaScript函数对象
2015/11/15 Javascript
解决js函数闭包内存泄露问题的办法
2016/01/25 Javascript
基于javascript实现九九乘法表
2016/03/27 Javascript
JavaScript String(字符串)对象的简单实例(推荐)
2016/08/31 Javascript
Bootstrap选项卡学习笔记分享
2017/02/13 Javascript
vuejs使用axios异步访问时用get和post的实例讲解
2018/08/09 Javascript
Vue实现用户自定义字段显示数据的方法
2018/08/28 Javascript
微信小程序实现展示评分结果功能
2019/02/15 Javascript
vue实现的网易云音乐在线播放和下载功能案例
2019/02/18 Javascript
vue源码中的检测方法的实现
2019/09/26 Javascript
jQuery HTML设置内容和属性操作实例分析
2020/05/20 jQuery
JS 逻辑判断不要只知道用 if-else 和 switch条件判断(小技巧)
2020/05/27 Javascript
JS实现放大镜效果
2020/09/21 Javascript
Python正则表达式匹配HTML页面编码
2015/04/08 Python
使用python将mysql数据库的数据转换为json数据的方法
2019/07/01 Python
python实现图片压缩代码实例
2019/08/12 Python
python os.path.isfile()因参数问题判断错误的解决
2019/11/29 Python
Django User 模块之 AbstractUser 扩展详解
2020/03/11 Python
python中entry用法讲解
2020/12/04 Python
美国名表在线商城:Ashford(支持中文)
2019/09/24 全球购物
周年庆典邀请函范文
2014/01/24 职场文书
煤矿班组长竞聘书
2014/03/31 职场文书
学校对教师的评语
2014/04/28 职场文书
研修心得体会
2014/09/04 职场文书
意外伤害赔偿协议书范文
2014/09/23 职场文书
Django cookie和session的应用场景及如何使用
2021/04/29 Python
用Python实现一个打字速度测试工具来测试你的手速
2021/05/28 Python
Go语言并发编程 sync.Once
2021/10/16 Golang
mysql主从复制的实现步骤
2021/10/24 MySQL