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 相关文章推荐
介绍几个array库的新函数 php
Dec 29 PHP
PHPMYADMIN 简明安装教程 推荐
Mar 07 PHP
PHP5中新增stdClass 内部保留类
Jun 13 PHP
关于PHP递归算法和应用方法介绍
Apr 15 PHP
PHP中使用sleep函数实现定时任务实例分享
Aug 21 PHP
smarty内置函数{loteral}、{ldelim}和{rdelim}用法实例
Jan 22 PHP
解读PHP中上传文件的处理问题
May 29 PHP
浅谈PHP值mysql操作类
Jun 29 PHP
PHP中类的自动加载的方法
Mar 17 PHP
Zend Framework框架中实现Ajax的方法示例
Jun 27 PHP
PHP设计模式之工厂方法设计模式实例分析
Apr 25 PHP
php实现数组重复数字统计实例
Sep 30 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笔记 字符串处理
2010/10/19 PHP
浅析Dos下运行php.exe,出现没有找到php_mbstring.dll 错误的解决方法
2013/06/29 PHP
PHP中exec函数和shell_exec函数的区别
2014/08/20 PHP
php读取csv数据保存到数组的方法
2015/01/03 PHP
php+mysqli实现批量执行插入、更新及删除数据的方法
2015/01/29 PHP
PHP与Web页面交互操作实例分析
2020/06/02 PHP
iis6+javascript Add an Extension File
2007/06/13 Javascript
javascript 自定义事件初探
2009/08/21 Javascript
使用nodejs开发cli项目实例
2015/06/03 NodeJs
详解js中构造流程图的核心技术JsPlumb
2015/12/08 Javascript
vue组件 $children,$refs,$parent的使用详解
2017/07/31 Javascript
基于jquery.page.js实现分页效果
2018/01/01 jQuery
从零开始搭建webpack+react开发环境的详细步骤
2018/05/18 Javascript
Vue 组件封装 并使用 NPM 发布的教程
2018/09/30 Javascript
jQuery单页面文字搜索插件jquery.fullsearch.js的使用方法
2020/02/04 jQuery
vant组件中 dialog的确认按钮的回调事件操作
2020/11/04 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
[33:19]完美世界DOTA2联赛PWL S2 PXG vs InkIce 第一场 11.26
2020/11/30 DOTA
[36:20]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.17
2020/12/18 DOTA
在Python中操作列表之list.extend()方法的使用
2015/05/20 Python
Python实现队列的方法
2015/05/26 Python
详谈python中冒号与逗号的区别
2018/04/18 Python
Python、 Pycharm、Django安装详细教程(图文)
2019/04/12 Python
Python while循环使用else语句代码实例
2020/02/07 Python
解决Jupyter NoteBook输出的图表太小看不清问题
2020/04/16 Python
HTML5之SVG 2D入门11—用户交互性(动画)介绍及应用
2013/01/30 HTML / CSS
汽车专业毕业生自荐信
2013/11/03 职场文书
最热门的自我评价
2013/12/30 职场文书
单位提档介绍信
2014/01/17 职场文书
成人继续教育实施方案
2014/03/01 职场文书
社区道德讲堂实施方案
2014/03/21 职场文书
司法局群众路线教育实践活动整改措施
2014/09/17 职场文书
机关作风建设自查报告
2014/10/22 职场文书
2015年七七事变78周年纪念活动方案
2015/05/06 职场文书
2015年九一八事变纪念活动实施方案
2015/05/06 职场文书
Oracle 触发器trigger使用案例
2022/02/24 Oracle