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 相关文章推荐
支持oicq头像的留言簿(一)
Oct 09 PHP
给apache2.2加上mod_encoding模块後 php5.2.0 处理url出现bug
Apr 12 PHP
php ss7.5的数据调用 (笔记)
Mar 08 PHP
php上的memcache和memcached两个pecl库
Mar 29 PHP
APACHE的AcceptPathInfo指令使用介绍
Jan 18 PHP
在wamp集成环境下升级php版本(实现方法)
Jul 01 PHP
php仿QQ验证码的实例分析
Jul 01 PHP
php对二维数组进行排序的简单实例
Dec 19 PHP
php获取URL中带#号等特殊符号参数的解决方法
Sep 02 PHP
教你php如何实现验证码
Jan 20 PHP
thinkPHP统计排行与分页显示功能示例
Dec 02 PHP
利用php-cli和任务计划实现刷新token功能的方法
May 03 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
模仿OSO的论坛(五)
2006/10/09 PHP
PHP 程序授权验证开发思路
2009/07/09 PHP
一个PHP数组应该有多大的分析
2009/07/30 PHP
跟我学Laravel之路由
2014/10/15 PHP
php实现的递归提成方案实例
2015/11/14 PHP
php $_SESSION会员登录实例分享
2021/01/19 PHP
PHP Laravel 上传图片、文件等类封装
2017/08/16 PHP
Smarty模板类内部原理实例分析
2019/07/03 PHP
php正则表达式使用方法整理集合
2020/01/31 PHP
ThinkPhP+Apache+PHPstorm整合框架流程图解
2020/11/23 PHP
PHP哈希表实现算法原理解析
2020/12/11 PHP
js向上无缝滚动,网站公告效果 具体代码
2013/11/18 Javascript
原生JavaScript生成GUID的实现示例
2014/09/05 Javascript
jQuery插件实现多级联动菜单效果
2015/12/01 Javascript
AngularJS入门教程之Helloworld示例
2016/12/25 Javascript
JS中append字符串包含onclick无效传递参数失败的解决方案
2016/12/26 Javascript
深入理解Javascript箭头函数中的this
2017/02/13 Javascript
微信小程序实现图片轮播及文件上传
2017/04/07 Javascript
JavaScript截屏功能的实现代码
2017/07/28 Javascript
webpack构建react多页面应用详解
2017/09/15 Javascript
Vue.js数字输入框组件使用方法详解
2019/10/19 Javascript
d3.js实现图形拖拽
2019/12/19 Javascript
Python open()文件处理使用介绍
2014/11/30 Python
在Linux命令行终端中使用python的简单方法(推荐)
2017/01/23 Python
numpy库与pandas库axis=0,axis= 1轴的用法详解
2019/05/27 Python
多个版本的python共存时使用pip的正确做法
2020/10/26 Python
巴西Bo.Bô官方在线商店:经营奢侈品时尚业务
2020/03/16 全球购物
村党支部换届选举方案
2014/05/02 职场文书
市级三好学生事迹材料
2014/08/27 职场文书
入党现实表现材料
2014/12/23 职场文书
2015年班干部工作总结
2015/04/29 职场文书
《女娲补天》教学反思
2016/02/20 职场文书
一文帮你理解PReact10.5.13源码
2021/04/03 Javascript
Python移位密码、仿射变换解密实例代码
2021/06/27 Python
24年收藏2000多部退役军用电台
2022/02/18 无线电