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 相关文章推荐
让你同时上传 1000 个文件 (二)
Oct 09 PHP
Dedecms V3.1 生成HTML速度的优化办法
Mar 18 PHP
Windows Apache2.2.11及Php5.2.9-1的安装与配置方法
Jun 08 PHP
php is_file 判断给定文件名是否为一个正常的文件
May 10 PHP
PHP读取xml方法介绍
Jan 12 PHP
解析PHP跳出循环的方法以及continue、break、exit的区别介绍
Jul 01 PHP
Laravel+jQuery实现AJAX分页效果
Sep 14 PHP
php中遍历二维数组并以表格的形式输出的方法
Jan 03 PHP
PHP实现的一致性Hash算法详解【分布式算法】
Mar 31 PHP
thinkPHP5框架分页样式类完整示例
Sep 01 PHP
Yii2.0 RESTful API 基础配置教程详解
Dec 26 PHP
YII2框架中actions的作用与使用方法示例
Mar 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实现的汉字拼音转换和公历农历转换类及使用示例
2014/07/01 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
用js判断用户浏览器是否是XP SP2的IE6
2007/03/08 Javascript
Discuz! 6.1_jQuery兼容问题
2008/09/23 Javascript
子页向父页传值示例
2013/11/27 Javascript
js动态改变select选择变更option的index值示例
2014/07/10 Javascript
js+HTML5基于过滤器从摄像头中捕获视频的方法
2015/06/16 Javascript
Css3制作变形与动画效果
2015/07/24 Javascript
Node.js的Web模板引擎ejs的入门使用教程
2016/06/06 Javascript
基于Vue如何封装分页组件
2016/12/16 Javascript
AngularJs表单校验功能实例代码
2017/02/09 Javascript
JavaScript实现经纬度转换成地址功能
2017/03/28 Javascript
Angular.Js之Scope作用域的学习教程
2017/04/27 Javascript
JavaScript实现省市县三级级联特效
2017/05/16 Javascript
EL表达式截取字符串的函数说明
2017/09/22 Javascript
微信小程序实现自上而下字幕滚动
2018/07/14 Javascript
JavaScript实现的拼图算法分析
2019/02/13 Javascript
vue实现手机端省市区区域选择
2019/09/27 Javascript
[01:16:12]完美世界DOTA2联赛PWL S2 FTD vs Inki 第一场 11.21
2020/11/23 DOTA
python中使用正则表达式的后向搜索肯定模式(推荐)
2017/11/11 Python
Python使用pip安装pySerial串口通讯模块
2018/04/20 Python
关于keras.layers.Conv1D的kernel_size参数使用介绍
2020/05/22 Python
清除canvas画布内容(点擦除+线擦除)
2020/08/12 HTML / CSS
中国茶叶、茶具一站式网上购物商城:醉品茶城
2018/07/03 全球购物
PHP高级工程师面试问题推荐
2013/01/18 面试题
请说出你所知道的线程同步的方法
2013/04/19 面试题
葬礼司仪主持词
2014/03/31 职场文书
清明节演讲稿
2014/05/27 职场文书
孩子教育的心得体会
2014/09/01 职场文书
先进工作者推荐材料
2014/12/23 职场文书
补充协议书
2015/01/28 职场文书
政审证明范文
2015/06/19 职场文书
如何做好工作总结!
2019/04/10 职场文书
详解Java实践之建造者模式
2021/06/18 Java/Android
mysql如何配置白名单访问
2021/06/30 MySQL
springboot读取resources下文件的方式详解
2022/06/21 Java/Android