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中Session的概念
Oct 09 PHP
PHP高自定义性安全验证码代码
Nov 27 PHP
php图片缩放实现方法
Feb 20 PHP
php+mysqli实现批量替换数据库表前缀的方法
Dec 29 PHP
php判断并删除空目录及空子目录的方法
Feb 11 PHP
在Windows系统下使用PHP生成Word文档的教程
Jul 03 PHP
thinkphp框架下404页面设置 仅三步
May 14 PHP
thinkphp3.2.3版本的数据库增删改查实现代码
Sep 22 PHP
php魔术方法功能与用法实例分析
Oct 19 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
Jul 26 PHP
CakePHP框架Model函数定义方法示例
Aug 04 PHP
ajax+php实现无刷新验证手机号的实例
Dec 22 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中simplexml_load_file函数用法实例
2014/11/12 PHP
php中随机函数mt_rand()与rand()性能对比分析
2014/12/01 PHP
PHP环境搭建的详细步骤
2016/06/30 PHP
PHP自定义函数格式化json数据示例
2016/09/14 PHP
基于Jquery的表格隔行换色,移动换色,点击换色插件
2010/12/22 Javascript
js自执行函数的几种不同写法的比较
2012/08/16 Javascript
jquery eval解析JSON中的注意点介绍
2013/08/23 Javascript
Jquery获取和修改img的src值的方法
2014/02/17 Javascript
javascript 兼容各个浏览器的事件
2015/02/04 Javascript
jQuery实现切换页面过渡动画效果
2015/10/29 Javascript
Vue.js报错Failed to resolve filter问题的解决方法
2016/05/25 Javascript
实例讲解JavaScript中的this指向错误解决方法
2016/06/13 Javascript
Vue.js实战之组件的进阶
2017/04/04 Javascript
vue 2.0项目中如何引入element-ui详解
2017/09/06 Javascript
Element InputNumber 计数器的实现示例
2020/08/03 Javascript
[02:28]DOTA2亚洲邀请赛 LGD战队巡礼
2015/02/03 DOTA
[00:44]TI7不朽珍藏III——军团指挥官不朽展示
2017/07/15 DOTA
使用Template格式化Python字符串的方法
2019/01/22 Python
pyqt 实现在Widgets中显示图片和文字的方法
2019/06/13 Python
把django中admin后台界面的英文修改为中文显示的方法
2019/07/26 Python
pytorch数据预处理错误的解决
2020/02/20 Python
简单的Python人脸识别系统
2020/07/14 Python
python实现数字炸弹游戏程序
2020/07/17 Python
python使用matplotlib绘制折线图的示例代码
2020/09/22 Python
python 使用openpyxl读取excel数据
2021/02/18 Python
英国DVD和蓝光碟片购买网站:Zoom.co.uk(电影和电视)
2019/09/23 全球购物
新西兰Bookabach:查找全球度假屋
2020/12/03 全球购物
简历中自我评价范文3则
2013/12/14 职场文书
环保标语口号
2014/06/13 职场文书
淘宝客服工作职责
2014/07/11 职场文书
幼儿园母亲节活动总结
2015/02/10 职场文书
工程部岗位职责范本
2015/04/11 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
Golang实现AES对称加密的过程详解
2021/05/20 Golang
AJAX实现省市县三级联动效果
2021/10/16 Javascript
在Centos 8.0中安装Redis服务器的教程详解
2022/03/21 Redis