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编程中八种常见的文件操作方式
Nov 19 PHP
php Rename 更改文件、文件夹名称
May 24 PHP
解析php通过cookies获取远程网页的指定代码
Jun 25 PHP
php几个预定义变量$_SERVER用法小结
Nov 07 PHP
php+jQuery.uploadify实现文件上传教程
Dec 26 PHP
PHP面向对象之后期静态绑定功能介绍
May 18 PHP
Yii2中DropDownList简单用法示例
Jul 18 PHP
PHP实现的数独求解问题示例
Apr 18 PHP
PHP测试框架PHPUnit组织测试操作示例
May 28 PHP
在TP5数据库中四个字段实现无限分类的示例
Oct 18 PHP
Yii框架安装简明教程
May 15 PHP
PHP 实现base64编码文件上传出现问题详解
Sep 01 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
解析curl提交GET,POST,Cookie的简单方法
2013/06/29 PHP
php生成图片缩略图的方法
2015/04/07 PHP
php使用curl通过代理获取数据的实现方法
2016/05/16 PHP
php禁用函数设置及查看方法详解
2016/07/25 PHP
php中用unset销毁变量并释放内存
2020/05/10 PHP
prototype class详解
2006/09/07 Javascript
用js实现小球的自由移动代码
2013/04/22 Javascript
JavaScript中判断原生函数检查function是否是原生代码
2014/09/09 Javascript
jQuery中filter()方法用法实例
2015/01/06 Javascript
jQuery使用之设置元素样式用法实例
2015/01/19 Javascript
javascript定时器完整实例
2015/02/10 Javascript
详解Javascript模板引擎mustache.js
2016/01/20 Javascript
下一代Bootstrap的5个特点 超酷炫!
2016/06/17 Javascript
jquery操作ul的一些操作笔记整理(干货)
2017/08/31 jQuery
JS Input里添加小图标的两种方法
2017/11/11 Javascript
微信小程序wx.previewImage预览图片实例详解
2017/12/07 Javascript
详解webpack babel的配置
2018/01/09 Javascript
vue通过路由实现页面刷新的方法
2018/01/25 Javascript
ES6 迭代器(Iterator)和 for.of循环使用方法学习(总结)
2018/02/08 Javascript
vuejs 切换导航条高亮(路由菜单高亮)的方法示例
2018/05/29 Javascript
Angular路由ui-router配置详解
2018/08/01 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
vue-cli 为项目设置别名的方法
2019/10/15 Javascript
微信小程序实现选项卡滑动切换
2020/10/22 Javascript
[02:27]《DAC最前线》之附加赛征程
2015/01/29 DOTA
[01:14]2019完美世界城市挑战赛(秋季赛)全国总决赛精彩花絮
2020/01/08 DOTA
python安装cx_Oracle模块常见问题与解决方法
2017/02/21 Python
对Python 3.5拼接列表的新语法详解
2018/11/08 Python
python面向对象入门教程之从代码复用开始(一)
2018/12/11 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
2019/01/14 Python
Python3标准库之threading进程中管理并发操作方法
2020/03/30 Python
俄罗斯金苹果网上化妆品和香水商店:Goldapple
2019/12/01 全球购物
总经理文秘岗位职责
2014/02/03 职场文书
《青蛙看海》教学反思
2014/04/23 职场文书
风之谷观后感
2015/06/11 职场文书
Python机器学习应用之工业蒸汽数据分析篇详解
2022/01/18 Python