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出错界面
Oct 09 PHP
php+AJAX传送中文会导致乱码的问题的解决方法
Sep 08 PHP
PHP多个版本的分析解释
Jul 21 PHP
php自动加载机制的深入分析
Jun 08 PHP
php根据操作系统转换文件名大小写的方法
Feb 24 PHP
php不写闭合标签的好处
Mar 04 PHP
PHP反射机制用法实例
Aug 28 PHP
thinkphp表单上传文件并将文件路径保存到数据库中
Jul 28 PHP
PHP 二级子目录(后台目录)设置二级域名
Mar 02 PHP
php获取linux命令结果的实例
Mar 13 PHP
PHP使用new StdClass()创建空对象的方法分析
Jun 06 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
Jun 13 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之第二天
2006/10/09 PHP
php 问卷调查结果统计
2015/10/08 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
2018/04/12 PHP
javascript动态改变img的src属性图片不显示的解决方法
2010/10/20 Javascript
javascript的数据类型、字面量、变量介绍
2012/05/23 Javascript
javascript学习笔记(八)正则表达式
2014/10/08 Javascript
jQuery中eq()方法用法实例
2015/01/05 Javascript
jQuery3.0中的buildFragment私有函数详解
2016/08/16 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
详解本地Node.js服务器作为api服务器的解决办法
2017/02/28 Javascript
vue.js 获取当前自定义属性值
2017/06/01 Javascript
JavaScript程序设计高级算法之动态规划实例分析
2017/11/24 Javascript
Chart.js 轻量级HTML5图表绘制工具库(知识整理)
2018/05/22 Javascript
vue2.0学习之axios的封装与vuex介绍
2018/05/28 Javascript
js中split()方法得到的数组长度问题
2018/07/19 Javascript
angularjs实现对表单输入改变的监控(ng-change和watch两种方式)
2018/08/29 Javascript
JavaScript 闭包的使用场景
2020/09/17 Javascript
[48:18]DOTA2-DPC中国联赛 正赛 RNG vs Dynasty BO3 第二场 1月29日
2021/03/11 DOTA
python将多个文本文件合并为一个文本的代码(便于搜索)
2011/03/13 Python
简单谈谈python中的Queue与多进程
2016/08/25 Python
Django之Mode的外键自关联和引用未定义的Model方法
2018/12/15 Python
python实现矩阵打印
2019/03/02 Python
计算机二级python学习教程(3) python语言基本数据类型
2019/05/16 Python
Python秒算24点实现及原理详解
2019/07/29 Python
如何理解Python中的变量
2020/06/01 Python
python 实现学生信息管理系统的示例
2020/11/28 Python
详解python中的异常和文件读写
2021/01/03 Python
CSS3 简写animation
2012/05/10 HTML / CSS
什么是方法的重载
2013/06/24 面试题
个人思想理论学习的自我鉴定
2013/11/30 职场文书
质量安全标语
2014/06/07 职场文书
商超业务员岗位职责
2015/02/13 职场文书
创业计划书之家教中心
2019/09/25 职场文书
如何用JavaScipt测网速
2021/05/09 Javascript
vue-cropper插件实现图片截取上传组件封装
2021/05/27 Vue.js
如何利用Python实现一个论文降重工具
2021/07/09 Python