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写的小东西
Dec 06 PHP
IIS+PHP+MySQL+Zend配置 (视频教程)
Dec 13 PHP
php 高性能书写
Dec 11 PHP
php读取csv文件后,uft8 bom导致在页面上显示出现问题的解决方法
Aug 10 PHP
PHP弹出提示框并跳转到新页面即重定向到新页面
Jan 24 PHP
php将12小时制转换成24小时制的方法
Mar 31 PHP
zend framework中使用memcache的方法
Mar 04 PHP
PHP针对多用户实现更换头像功能
Sep 04 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
Sep 16 PHP
PHP设计模式之工厂模式详解
Oct 24 PHP
PHP使用PDO抽象层获取查询结果的方法示例
May 10 PHP
解决php写入数据库乱码的问题
Sep 17 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自动更新新闻DIY
2006/10/09 PHP
一个用于网络的工具函数库
2006/10/09 PHP
PHP调用Linux的命令行执行文件压缩命令
2013/01/27 PHP
thinkPHP5 tablib标签库自定义方法详解
2017/05/10 PHP
GreyBox技术总结(转)
2010/11/23 Javascript
使用firebug进行调试javascript的示例
2013/12/16 Javascript
javascript解析json数据的3种方式
2014/05/08 Javascript
jquery修改网页背景颜色通过css方法实现
2014/06/06 Javascript
jfinal与bootstrap的登录跳转实战演习
2015/09/22 Javascript
jQuery中的基本选择器用法学习教程
2016/04/14 Javascript
AngularJS在IE8的不支持的解决方法
2016/05/13 Javascript
Web前端新人笔记之jquery入门心得(新手必看)
2016/05/17 Javascript
domReady的实现案例
2016/11/23 Javascript
jQuery电话号码验证实例
2017/01/05 Javascript
详解Vue-基本标签和自定义控件
2017/03/24 Javascript
vue使用axios时关于this的指向问题详解
2017/12/22 Javascript
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
让Vue也可以使用Redux的方法
2018/05/23 Javascript
layer弹出子iframe层父子页面传值的实现方法
2018/11/22 Javascript
JavaScript中var的重要性实例分析
2019/07/09 Javascript
解决layui数据表格Date日期格式的回显Object的问题
2019/09/19 Javascript
Vue中rem与postcss-pxtorem的应用详解
2019/11/20 Javascript
[01:51]2014DOTA2西雅图邀请赛 MVP 外卡赛black场间采访
2014/07/09 DOTA
wxpython实现按钮切换界面的方法
2019/11/19 Python
python统计字符串中字母出现次数代码实例
2020/03/02 Python
python tkinter之顶层菜单、弹出菜单实例
2020/03/04 Python
利用简洁的图片预加载组件提升html5移动页面的用户体验
2016/03/11 HTML / CSS
Roots加拿大官网:加拿大休闲服饰品牌
2016/10/24 全球购物
意大利顶级奢侈品电商:LUISAVIAROMA(支持中文)
2020/05/26 全球购物
酒店副总岗位职责
2013/12/24 职场文书
捐书寄语赠言
2014/01/18 职场文书
领导班子个人对照检查剖析材料
2014/09/29 职场文书
2014年环境整治工作总结
2014/12/10 职场文书
会议开幕词
2015/01/28 职场文书
求职简历自我评价怎么写
2015/03/10 职场文书
JavaScript ES6的函数拓展
2022/01/18 Javascript