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 相关文章推荐
桌面中心(四)数据显示
Oct 09 PHP
PHP+JS无限级可伸缩菜单详解(简单易懂)
Jan 02 PHP
解析php中的fopen()函数用打开文件模式说明
Jun 20 PHP
PHP生成自定义长度随机字符串的函数分享
May 04 PHP
Yii实现多按钮保存与提交的方法
Dec 03 PHP
PHP中的替代语法介绍
Jan 09 PHP
Laravel使用Caching缓存数据减轻数据库查询压力的方法
Mar 15 PHP
php使用CURL模拟GET与POST向微信接口提交及获取数据的方法
Sep 23 PHP
PHP实现限制IP访问及提交次数的方法详解
Jul 17 PHP
PHP流Streams、包装器wrapper概念与用法实例详解
Nov 17 PHP
PHP排序算法之快速排序(Quick Sort)及其优化算法详解
Apr 21 PHP
PHP 对象继承原理与简单用法示例
Apr 21 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使用preg_split和explode分割textarea存放内容的方法分析
2017/07/03 PHP
农历与西历对照
2006/09/06 Javascript
js 发个判断字符串是否为符合标准的函数
2009/04/27 Javascript
GreyBox技术总结(转)
2010/11/23 Javascript
解决JS浮点数运算出现Bug的方法
2013/03/12 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
node.js中的fs.close方法使用说明
2014/12/17 Javascript
AngularJS基础学习笔记之指令
2015/05/10 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
AngularJs ng-route路由详解及实例代码
2016/09/14 Javascript
表单input项使用label同时引用Bootstrap库导致input点击效果区增大问题
2016/10/11 Javascript
AngularJS实现Input格式化的方法
2016/11/07 Javascript
解决AngualrJS页面刷新导致异常显示问题
2017/04/20 Javascript
nodejs用gulp管理前端文件方法
2018/06/24 NodeJs
微信小程序框架的页面布局代码
2019/08/17 Javascript
Vue v-bind动态绑定class实例方法
2020/01/15 Javascript
Vue记住滚动条和实现下拉加载的完美方法
2020/07/31 Javascript
Python2.x与Python3.x的区别
2016/01/14 Python
Python生成8位随机字符串的方法分析
2017/12/05 Python
python 提取key 为中文的json 串方法
2018/12/31 Python
基于python分析你的上网行为 看看你平时上网都在干嘛
2019/08/13 Python
利用python汇总统计多张Excel
2020/09/22 Python
python爬取豆瓣电影排行榜(requests)的示例代码
2021/02/18 Python
英国户外玩具儿童游乐设备网站:TP Toys(蹦床、攀爬框架、秋千、滑梯和游戏屋)
2018/04/09 全球购物
英国票务网站:Ticketmaster英国
2018/08/27 全球购物
编写一个类体现构造,公有,私有方法,静态,私有变量
2013/08/10 面试题
采购部主管岗位职责
2014/01/01 职场文书
银行演讲稿范文
2014/01/03 职场文书
最新奶茶店创业计划书
2014/01/25 职场文书
幼儿园中班下学期评语
2014/04/18 职场文书
企业授权委托书范本
2014/09/22 职场文书
八年级上册语文教学计划
2015/01/22 职场文书
2015年司机年终工作总结
2015/05/14 职场文书
Python自然语言处理之切分算法详解
2021/04/25 Python
只用Python就可以制作的简单词云
2021/06/07 Python
分析JVM源码之Thread.interrupt系统级别线程打断
2021/06/29 Java/Android