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(视频)Http下载
Dec 12 PHP
Zend Studio for Eclipse的java.lang.NullPointerException错误的解决方法
Dec 06 PHP
php 3行代码的分页算法(求起始页和结束页)
Oct 21 PHP
PHP高级对象构建 工厂模式的使用
Feb 05 PHP
php适配器模式介绍
Aug 14 PHP
php使用pdo连接并查询sql数据库的方法
Dec 24 PHP
PHP查看当前变量类型的方法
Jul 31 PHP
在WordPress中实现发送http请求的相关函数解析
Dec 29 PHP
简单PHP会话(session)说明介绍
Aug 21 PHP
微信 getAccessToken方法详解及实例
Nov 23 PHP
php 三元运算符实例详细介绍
Dec 15 PHP
PHP中递归的实现实例详解
Nov 14 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写入WRITE编码为UTF8的文件的实现代码
2008/07/07 PHP
php实现微信公众号无限群发
2015/10/11 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
Javascript 去除数组的重复元素
2010/05/04 Javascript
使用jQuery.Validate进行客户端验证(初级篇) 不使用微软验证控件的理由
2010/06/28 Javascript
基于Jquery的跨域传输数据(JSONP)
2011/03/10 Javascript
JavaScript单元测试ABC
2012/04/12 Javascript
extjs_02_grid显示本地数据、显示跨域数据
2014/06/23 Javascript
javascript记录文本框内文字个数检测文字个数变化
2014/10/14 Javascript
Javscript调用iframe框架页面中函数的方法
2014/11/01 Javascript
JavaScript小技巧整理
2015/12/30 Javascript
VUE元素的隐藏和显示(v-show指令)
2017/06/23 Javascript
基于jquery实现左右上下移动效果
2018/05/02 jQuery
jquery 通过ajax请求获取后台数据显示在表格上的方法
2018/08/08 jQuery
vue.js 输入框输入值自动过滤特殊字符替换中问标点操作
2020/08/31 Javascript
基于JavaScript实现轮播图效果
2021/01/02 Javascript
[01:50:49]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第三场 1月24日
2021/03/11 DOTA
python使用PyGame模块播放声音的方法
2015/05/20 Python
初步讲解Python中的元组概念
2015/05/21 Python
Python测试人员需要掌握的知识
2018/02/08 Python
tensorboard 可以显示graph,却不能显示scalar的解决方式
2020/02/15 Python
pytorch实现保证每次运行使用的随机数都相同
2020/02/20 Python
想学画画?python满足你!
2020/12/24 Python
PyCharm 光标变成黑块的解决方式
2021/02/06 Python
美国经典刺绣和字母儿童服装特卖:Smocked Auctions
2018/07/16 全球购物
Anya Hindmarch官网:奢侈设计师手袋及配饰
2018/11/15 全球购物
eBay意大利购物网站:eBay.it
2019/09/04 全球购物
毕业生自荐信
2013/12/14 职场文书
教师校本培训方案
2014/02/26 职场文书
中班上学期幼儿评语
2014/04/30 职场文书
党的群众路线教育实践活动个人自我剖析材料
2014/10/07 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书
2015年助残日活动总结
2015/03/27 职场文书
聊一聊python常用的编程模块
2021/05/14 Python
python正则表达式re.search()的基本使用教程
2021/05/21 Python
国产动画《万圣街》日语配音版制作决定!
2022/03/20 国漫