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下防止单引号,双引号在接受页面转义的设置方法
Sep 25 PHP
php 三维饼图的实现代码
Sep 28 PHP
PHP 编写大型网站问题集
May 07 PHP
PHP5.3的垃圾回收机制(动态存储分配方案)深入理解
Dec 10 PHP
兼容各大浏览器带关闭按钮的漂浮多组图片广告代码
Jun 05 PHP
Yii框架调试心得--在页面输出执行sql语句
Dec 25 PHP
PHP、Java des加密解密实例
Apr 27 PHP
程序员的表白神器“520”大声喊出来
May 20 PHP
php 函数使用可变数量的参数方法
May 02 PHP
PHP实现的链式队列结构示例
Sep 15 PHP
PHP基于curl实现模拟微信浏览器打开微信链接的方法示例
Feb 15 PHP
详解Laravel服务容器的优势
May 29 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 disk_free_space 返回目录可用空间
2010/05/10 PHP
php异常处理技术,顶级异常处理器
2012/06/13 PHP
PHP基于GD库的缩略图生成代码(支持jpg,gif,png格式)
2014/06/19 PHP
php实现数组中索引关联数据转换成json对象的方法
2015/07/08 PHP
php检测文本的编码
2015/07/26 PHP
extjs grid取到数据而不显示的解决
2008/12/29 Javascript
写入cookie的JavaScript代码库 cookieLibrary.js
2009/10/24 Javascript
AlertBox 弹出层信息提示框效果实现步骤
2010/10/11 Javascript
JavaScript Array Flatten 与递归使用介绍
2011/10/30 Javascript
ASP.NET jQuery 实例5 (显示CheckBoxList成员选中的内容)
2012/01/13 Javascript
自写的jQuery异步加载数据添加事件
2014/05/15 Javascript
JQuery1.8 判断元素是否绑定事件的方法
2014/07/10 Javascript
JavaScript获取Url里的参数
2014/12/18 Javascript
JavaScript面向对象之私有静态变量实例分析
2016/01/14 Javascript
jQuery实现滚动鼠标放大缩小图片的方法(附demo源码下载)
2016/03/05 Javascript
Javascript中的迭代、归并方法详解
2016/06/14 Javascript
PHP捕捉异常中断的方法
2016/10/24 Javascript
vue之nextTick全面解析
2017/05/17 Javascript
快速将Vue项目升级到webpack3的方法步骤
2017/09/14 Javascript
面试题:react和vue的区别分析
2019/04/08 Javascript
详解JS深拷贝与浅拷贝
2020/08/04 Javascript
使用grappelli为django admin后台添加模板
2014/11/18 Python
浅谈Pandas:Series和DataFrame间的算术元素
2018/12/22 Python
python变量赋值方法(可变与不可变)
2019/01/12 Python
Python2与Python3的区别实例分析
2019/04/11 Python
Pycharm和Idea支持的vim插件的方法
2020/02/21 Python
python 数据库查询返回list或tuple实例
2020/05/15 Python
Python-openCV开运算实例
2020/07/05 Python
解决Firefox下不支持outerHTML问题代码分享
2014/06/04 HTML / CSS
前端使用canvas生成盲水印的加密解密的实现
2020/12/16 HTML / CSS
Watchshop德国:欧洲在线手表No.1
2019/06/20 全球购物
乌克兰在线药房:Аптека24
2019/10/30 全球购物
档案管理员岗位职责
2013/12/01 职场文书
学生周末长期请假条
2014/02/15 职场文书
元旦主持词开场白
2015/05/29 职场文书
Python几种酷炫的进度条的方式
2022/04/11 Python