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 在线翻译函数代码
May 07 PHP
PHP XML数据解析代码
May 26 PHP
让PHP COOKIE立即生效,不用刷新就可以使用
Mar 09 PHP
基于AppServ,XAMPP,WAMP配置php.ini去掉警告信息(NOTICE)的方法详解
May 07 PHP
php实现图片缩放功能类
Dec 18 PHP
php命名空间学习详解
Feb 27 PHP
体育彩票排列三组选三算法分享
Mar 07 PHP
PHP改进计算字符串相似度的函数similar_text()、levenshtein()
Oct 27 PHP
php中二维数组排序问题方法详解
Aug 28 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
Nov 15 PHP
Laravel重定向,a链接跳转,控制器跳转示例
Oct 22 PHP
如何理解PHP核心特性命名空间
May 28 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中addslashes函数与sql防注入
2014/11/17 PHP
PHP严重致命错误处理:php Fatal error: Cannot redeclare class or function
2017/02/05 PHP
原生JS实现Ajax通过POST方式与PHP进行交互的方法示例
2018/05/12 PHP
laravel5.6框架操作数据curd写法(查询构建器)实例分析
2020/01/26 PHP
搭建PhpStorm+PhpStudy开发环境的超详细教程
2020/09/17 PHP
javascript 极速 隐藏/显示万行表格列只需 60毫秒
2009/03/28 Javascript
同一个表单 根据要求递交到不同页面的实现方法小结
2009/08/05 Javascript
JS 文件传参及处理技巧分析
2010/05/13 Javascript
jquery处理json数据实例分析
2014/06/03 Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
2015/07/31 Javascript
JS实现点击复选框将按钮或文本框变为灰色不可用的方法
2015/08/11 Javascript
Jquery easyui 实现动态树
2015/11/17 Javascript
JS实现的多张图片轮流播放幻灯片效果
2016/07/22 Javascript
nodejs模块nodemailer基本使用-邮件发送示例(支持附件)
2017/03/28 NodeJs
JS实现问卷星自动填问卷脚本并在两秒自动提交功能
2020/06/17 Javascript
VueJS事件处理器v-on的使用方法
2017/09/27 Javascript
jquery-file-upload 文件上传带进度条效果
2017/11/21 jQuery
vue双向数据绑定知识点总结
2018/04/18 Javascript
nodejs npm错误Error:UNKNOWN:unknown error,mkdir 'D:\Develop\nodejs\node_global'at Error
2019/03/02 NodeJs
解决Tensorflow使用pip安装后没有model目录的问题
2018/06/13 Python
对Python 数组的切片操作详解
2018/07/02 Python
flask框架单元测试原理与用法实例分析
2019/07/23 Python
使用Python生成200个激活码的实现方法
2019/11/22 Python
怎么快速自学python
2020/06/22 Python
浅析Python模块之间的相互引用问题
2021/02/26 Python
html5的websockets全双工通信详解学习示例
2014/02/26 HTML / CSS
Lee牛仔裤澳大利亚官网:美国著名牛仔裤品牌
2017/09/02 全球购物
光盘行动倡议书
2014/02/02 职场文书
教育学习自我评价
2014/02/03 职场文书
大学生就业自我推荐信
2014/05/10 职场文书
师范生求职自荐信
2014/06/14 职场文书
财务工作失职检讨书
2014/11/21 职场文书
防汛通知
2015/04/25 职场文书
2015年行风建设工作总结
2015/05/15 职场文书
Mac M1安装mnmp (Mac+Nginx+MySQL+PHP) 开发环境
2021/03/29 PHP
python数据分析之单因素分析线性拟合及地理编码
2022/06/25 Python