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分页函数
Jul 08 PHP
PHP中的超全局变量
Oct 09 PHP
国内php原创论坛
Oct 09 PHP
discuz程序的PHP加密函数原理分析
Aug 05 PHP
处理单名多值表单的详解
Jun 08 PHP
详解YII关联查询
Jan 10 PHP
Symfony2实现在doctrine中内置数据的方法
Feb 05 PHP
php实现生成验证码实例分享
Apr 10 PHP
简单谈谈PHP中的trait
Feb 25 PHP
php+ajax实现异步上传文件或图片功能
Jul 18 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
Dec 26 PHP
PHP实现求连续子数组最大和问题2种解决方法
Dec 26 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
Terran魔法科技
2020/03/14 星际争霸
php trim 去除空字符的定义与语法介绍
2010/05/31 PHP
PHP查询MySQL大量数据的时候内存占用分析
2011/07/22 PHP
对于PHP 5.4 你必须要知道的
2013/08/07 PHP
PHP积分兑换接口实例
2015/02/09 PHP
PHP curl伪造IP地址和header信息代码实例
2015/04/27 PHP
PHP实现C#山寨ArrayList的方法
2015/07/16 PHP
PHP读取配置文件类实例(可读取ini,yaml,xml等)
2015/07/28 PHP
PHP实现统计所有字符在字符串中出现次数的方法
2017/10/17 PHP
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
2010/06/28 Javascript
js编码之encodeURIComponent使用介绍(asp,php)
2012/03/01 Javascript
网页打开自动最大化的js代码
2012/08/22 Javascript
JS上传图片前的限制包括(jpg jpg gif及大小高宽)等
2012/12/19 Javascript
JQuery下拉框应用示例介绍
2014/04/23 Javascript
JS实现仿京东淘宝竖排二级导航
2014/12/08 Javascript
jQuery性能优化技巧分析
2015/02/20 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
2016/05/28 Javascript
BootStrap智能表单实战系列(四)表单布局介绍
2016/06/13 Javascript
JS实现隐藏同级元素后只显示JS文件内容的方法
2016/09/04 Javascript
超级简易的JS计算器实例讲解(实现加减乘除)
2017/08/08 Javascript
微信小程序实现倒计时60s获取验证码
2020/04/17 Javascript
使用 Node.js 开发资讯爬虫流程
2018/01/07 Javascript
vue实现修改图片后实时更新
2019/11/14 Javascript
Python中下划线的使用方法
2015/03/27 Python
在Python中合并字典模块ChainMap的隐藏坑【推荐】
2019/06/27 Python
Python多线程模块Threading用法示例小结
2019/11/09 Python
Python文件时间操作步骤代码详解
2020/04/13 Python
Python中常见的数制转换有哪些
2020/05/27 Python
css3教程之倾斜页面
2014/01/27 HTML / CSS
Artist Guitars新西兰:乐器在线商店
2017/09/17 全球购物
什么时候用assert
2015/05/08 面试题
研究生论文答辩开场白
2015/05/27 职场文书
七年级英语教学反思
2016/02/15 职场文书
中国古代史学名著《战国策》概述
2019/08/09 职场文书
go设置多个GOPATH的方式
2021/05/05 Golang
让文件路径提取变得更简单的Python Path库
2021/05/27 Python