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 相关文章推荐
获取URL文件名后缀
Oct 24 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
Jan 03 PHP
PHP中使用strpos函数实现屏蔽敏感关键字功能
Aug 21 PHP
ThinkPHP打开验证码页面显示乱码的解决方法
Dec 18 PHP
学习php设计模式 php实现门面模式(Facade)
Dec 07 PHP
Yii2超好用的日期和时间组件(值得收藏)
May 05 PHP
PHP基于mssql扩展远程连接MSSQL的简单实现方法
Oct 08 PHP
php获取linux命令结果的实例
Mar 13 PHP
在Laravel中使用DataTables插件的方法
May 29 PHP
laravel使用Faker数据填充的实现方法
Apr 12 PHP
php常用字符串查找函数strstr()与strpos()实例分析
Jun 21 PHP
关于laravel框架中的常用目录路径函数
Oct 23 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
咖啡豆要不要放冰箱的原因
2021/03/04 冲泡冲煮
php设计模式 Adapter(适配器模式)
2011/06/26 PHP
微信自定义菜单的处理开发示例
2015/04/16 PHP
WordPress中对访客评论功能的一些优化方法
2015/11/24 PHP
php实现的简单数据库操作Model类
2016/11/16 PHP
PHP+MySQL实现模糊查询员工信息功能示例
2018/06/01 PHP
JavaScript 三种不同位置代码的写法
2009/10/25 Javascript
javascript下数值型比较难点说明
2010/06/07 Javascript
基于SVG的web页面图形绘制API介绍及编程演示
2013/06/28 Javascript
5秒后跳转到另一个页面的js代码
2013/10/12 Javascript
JS控制输入框内字符串长度
2014/05/21 Javascript
jQuery结合HTML5制作的爱心树表白动画
2015/02/01 Javascript
jquery实现点击其他区域时隐藏下拉div和遮罩层的方法
2015/12/23 Javascript
详解jquery事件delegate()的使用方法
2016/01/25 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
Node.js安装配置图文教程
2017/05/10 Javascript
jQuery制作全屏宽度固定高度轮播图(实例讲解)
2017/07/08 jQuery
bootstrap中日历范围选择插件daterangepicker的使用详解
2018/04/17 Javascript
基于vue2.0实现仿百度前端分页效果附实现代码
2018/10/30 Javascript
Vue Prop属性功能与用法实例详解
2019/02/23 Javascript
vue实现拖拽的简单案例 不超出可视区域
2019/07/25 Javascript
如何通过vscode运行调试javascript代码
2020/07/24 Javascript
Centos下实现安装Python3.6和Python2共存
2018/08/15 Python
python实现AES和RSA加解密的方法
2019/03/28 Python
Django Celery异步任务队列的实现
2019/07/24 Python
Python在Matplotlib图中显示中文字体的操作方法
2019/07/29 Python
Python request post上传文件常见要点
2020/11/20 Python
斯图尔特·韦茨曼鞋加拿大官网:Stuart Weitzman加拿大
2019/10/13 全球购物
Ruby如何进行文件操作
2014/07/17 面试题
比赛口号大全
2014/06/10 职场文书
初婚初育证明范本
2014/11/24 职场文书
初中毕业生自我评价
2015/03/02 职场文书
一个都不能少观后感
2015/06/04 职场文书
详解Flask开发技巧之异常处理
2021/06/15 Python
javascript代码简写的几种常用方式汇总
2021/08/23 Javascript
Java字符缓冲流BufferedWriter
2022/04/09 Java/Android