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 header函数使用教程
Sep 05 PHP
PHP将session信息存储到数据库的类实例
Mar 04 PHP
php实现TCP端口检测的方法
Apr 01 PHP
微信公众平台实现获取用户OpenID的方法
Apr 15 PHP
php猴子选大王问题解决方法
May 12 PHP
PHP sleep()函数, usleep()函数
Aug 25 PHP
php 三大特点:封装,继承,多态
Feb 19 PHP
完美解决在ThinkPHP控制器中命名空间的问题
May 05 PHP
PHP中phar包的使用教程
Jun 14 PHP
php抽象类和接口知识点整理总结
Aug 02 PHP
php创建多级目录与级联删除文件的方法示例
Sep 12 PHP
基于php+MySql实现学生信息管理系统实例
Aug 04 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
fleaphp常用方法分页之Pager使用方法
2011/04/23 PHP
PHP向浏览器输出内容的4个函数总结
2014/11/17 PHP
Zend Framework动作助手FlashMessenger用法详解
2016/03/05 PHP
php快速导入大量数据的实例方法
2019/09/23 PHP
javascript 学习之旅 (3)
2009/02/05 Javascript
jqGrid增加时--判断开始日期与结束日期(实例解析)
2013/11/08 Javascript
jQuery计算textarea中文字数(剩余个数)的小程序
2013/11/28 Javascript
JS获取计算机mac地址以及IP的实现方法
2014/01/08 Javascript
JavaScript编程的10个实用小技巧
2014/04/18 Javascript
jQuery中ajax的post()方法用法实例
2014/12/26 Javascript
js使用split函数按照多个字符对字符串进行分割的方法
2015/03/20 Javascript
JS实现带有抽屉效果的产品类网站多级导航菜单代码
2015/09/15 Javascript
javascript中checkbox使用方法实例演示
2015/11/19 Javascript
Bootstrap教程JS插件弹出框学习笔记分享
2016/05/17 Javascript
JS 实现可停顿的垂直滚动实例代码
2016/11/23 Javascript
JavaScript实现定时页面跳转功能示例
2017/02/14 Javascript
JavaScript 中的 this 简单规则
2017/09/19 Javascript
Angular表格神器ui-grid应用详解
2017/09/29 Javascript
关于vue v-for循环解决img标签的src动态绑定问题
2018/09/18 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
使用Vue调取接口,并渲染数据的示例代码
2019/10/28 Javascript
JavaScript ECMA-262-3 深入解析(一):执行上下文实例分析
2020/04/25 Javascript
Node.js API详解之 os模块用法实例分析
2020/05/06 Javascript
在vant 中使用cell组件 定义图标该图片和位置操作
2020/11/02 Javascript
python根据时间生成mongodb的ObjectId的方法
2015/03/13 Python
Python下实现的RSA加密/解密及签名/验证功能示例
2017/07/17 Python
python用post访问restful服务接口的方法
2018/12/07 Python
Python 3.6打包成EXE可执行程序的实现
2019/10/18 Python
Python数据持久化存储实现方法分析
2019/12/21 Python
气象学专业个人求职信
2014/04/22 职场文书
优秀研究生主要事迹
2014/06/03 职场文书
应届生自荐信
2014/06/30 职场文书
语文教师个人工作总结
2015/02/06 职场文书
在校生证明
2015/06/17 职场文书
Python如何识别银行卡卡号?
2021/06/10 Python
mysql数据插入覆盖和时间戳的问题及解决
2022/03/25 MySQL