laravel之Eloquent关联

news/2024/7/24 7:38:30

定义

  • 模型 用对象表示的表实例,负责与数据库的交互逻辑构建
  • 关联模型 要连接到的最终模型
  • 关联方法 返回一个关联关系的方法
  • 关联属性 $with属性 由关联方法名组成的数组,通常用于渴求式加载
  • 连接表 又称中间表,通常用于多对多关系
  • 主键 模型的唯一标识符
  • 外键 模型对外的通路
  • 正向 模型主键匹配关联模型外键
  • 反向 模型外键匹配关键模型主键
  • 父级模型 拥有下属分支的模型,典型的一对多关系,一则为父级模型
  • 子级模型 作为某一模型的后继模型,该模型对象对前驱模型有依赖
  • 默认模型

关联关系

  • 一对一 (正向 A->B)
    hasOne('App\Phone','foreign_key','local_key')
    hasOne 方法的第一个参数 是最终想到达的关联模型的类名,
    Eloquent 会基于当前模型名+_id决定关联模型外键名称
    第三个参数,为当前模型的非id以外的自定义关联外键名

  • 一对一(反向 B->A)
    belongsTo('App\User', 'foreign_key', 'other_key')
    第一个参数 要访问的模型类名,俗称关联模型
    第二个参数,默认关联方法名+_id为模型的外键名
    第三个参数,指定父级数据表自定义键 父级模型没有使用id为主键,或者希望使用不同的字段来连接子模型

  • 默认模型
    *空对象模式,传递数组或闭包给withDefault方法

        belongsTo('App\User')->withDefault();  
        belongsTo('App\User')->withDefault(['name' => '游客',]);  
        belongsTo('App\User')->withDefault(function($user){$user->name = '游客'});
    
  • 一对多(正向)
    Eloquent 使用父级模型名的「snake case」形式、加上 _id 后缀名作为外键字段
    所有的关联还可以作为查询语句构造器使用, 可通过传递额外参数来覆盖默认使用的外键与本地键。
    hasMany(‘App\Comment’)
    hasMany(‘App\Comment’, ‘foreign_key’)
    hasMany(‘App\Comment’, ‘foreign_key’, ‘local_key’)

    反向关联
    获得一篇文章的所有评论,接着再定义一个通过评论获得所属文章的关联
    hasMany 关联的反向关联,在子级模型中使用 belongsTo 方法定义

    //comment.php
    
    //Get the post that owns the comment.
    public function post()
    {
    return $this->belongsTo('App\Post');
    }

    示例: 父级模型,子级模型,外键,主键
    上述默认,子级模型comment的外键是post+_id (关联名+_id),父级模型post使用id作为主键

  • 多对多(连接表)
    users roles role_user
    belongsToMany('App\Role', 'role_user', 'user_id', 'role_id')
    第一个参数 目标关联模型类名
    第二个参数连接表名 由关联的两个模型名按照字母顺序确定
    第三个参数 定义此关联的模型在连接表里的外键名
    第四个参数 另一个模型在连接表里的外键名

    定义反向关联
    定义多对多关联的反向关联,在对方模型里再次调用 belongsToMany 方法即可。

    获取中间表字段
    每个 Role 模型对象,代表中间表的一个模型对象
    默认情况下,pivot 对象只包含两个关联模型的键。

        belongsToMany('App\Role')->withPivot('column1', 'column2')
        belongsToMany('App\Role')->withTimestamps()
        belongsToMany('App\Podcast')->as('subscription') ->withTimestamps() //自定义 pivot 属性名称  

关联操作

  • 一对多 belongsTo关联
    注意需要使用save方法持久化存储
    associate 方法在子模型中设置外键
    dissociate 方法 当移除 belongsTo 关联时, 将关联外键设置为 null:

        $account = App\Account::find(10);
        $user->account()->associate($account);
        $user->save();
    
        $user->account()->dissociate();
        $user->save();
    
  • 多对多关联 belongsToMany 中间表
    允许传递一个ID数组
    attach 向中间表插入一条记录
    detach 移除多对多关联记录

        $user = App\User::find(1);
        $user->roles()->attach($roleId);
    
        // 添加附加数据
        $user->roles()->attach($roleId, ['expires' => $expires]);
    
        // 移除用户的一个角色...
        $user->roles()->detach($roleId);
        // 移除用户的所有角色...
        $user->roles()->detach();
    
        $user = App\User::find(1);
        $user->roles()->detach([1, 2, 3]);
    
        $user->roles()->attach([
            1 => ['expires' => $expires],
            2 => ['expires' => $expires]
        ]);

    同步关联
    sync 所有未在 ID 数组中的记录都将会被移除

        $user->roles()->sync([1, 2, 3]);  
        //传递额外数据  
        $user->roles()->sync([1 => ['expires' => true], 2, 3]);  
        //不移除现有的 ID  
        $user->roles()->syncWithoutDetaching([1, 2, 3]);

    切换关联
    toggle 方法用于「切换」给定 ID 数组的附加状态。

        $user->roles()->toggle([1, 2, 3]);

    在中间表上保存额外的数据
    当处理多对多关联时,save 方法接收一个额外的数据数组作为第二个参数

        `App\User::find(1)->roles()->save($role, ['expires' => $expires]);`  

    更新中间表记录
    updateExistingPivot此方法接收中间表的外键与要更新的数据数组进行更新

        $user = App\User::find(1);
        $user->roles()->updateExistingPivot($roleId, $attributes);
  • 更新父级时间戳
    在子模型加一个包含关联名称的 touches
    当一个模型属 belongsTo 或者 belongsToMany 另一个模型时

        namespace App;
    
        use Illuminate\Database\Eloquent\Model;
    
        class Comment extends Model
        {
            /**
            * 要触发的所有关联关系。
            *
            * @var array
            */
            protected $touches = ['post'];
    
            /**
            * 评论所属文章。
            */
            public function post()
            {
                return $this->belongsTo('App\Post');
            }
        }

    使用场景
    更新子模型导致更新父模型时间戳,在子模型加一个包含关联名称的 touches 属性即可。
    当 Comment 模型被更新时,您要自动「触发」父级 Post 模型的 updated_at 时间戳的更新。

  • 特例
    通常多对多形式 A->B->C
    但也有 A->B->A 粉丝与粉主
    更有 A<->A 多态‘中间表’维护在单张表内


http://www.niftyadmin.cn/n/642824.html

相关文章

QT tcpserver启动监听SIGSEGV错误

QT tcpserver启动监听SIGSEGV错误 --------------------------- Signal Received --------------------------- <p>The inferior stopped because it received a signal from the operating system.<p><table><tr><td>Signal name : </td>…

SSM框架报错:元素 ‘annotation-driven‘ 必须不含字符 [子级], 因为该类型的内容类型为“仅元素”。

在SSM框架整合fastjson的时候出了一个莫名其妙的BUG&#xff0c;报错内容为&#xff1a;元素 ‘mvc:annotation-driven’ 必须不含字符 [子级], 因为该类型的内容类型为“仅元素”。 我的mvc:annotation-driven内容为&#xff1a; <mvc:annotation-driven><mvc:mess…

JSON数组去重

/* * JSON数组去重 * param: [array] json Array * param: [string] 唯一的key名&#xff0c;根据此键名进行去重 */function uniqueArray(array, key,mergekey){ var result [array[0]]; for(var i 1; i < array.length; i){ var item array[i]; var repe…

非网管和网管交换机区别

交换机可以分为网管交换机以及非网管交换机&#xff0c;而非网管交换机又称为傻瓜型交换机&#xff0c;不需要任何设置&#xff0c;插上网线即可。 什么叫非网管交换机&#xff1f; 非网管交换机&#xff0c;是相对网管型交换机而言的。网管型交换机的数据&#xff0c;会通过简…

QT error: undefined reference to `__imp__ZN12QSqlDatabase7driversEv‘报错

D:\QT_Project\src17_1\main.cpp:10: error: undefined reference to __imp__ZN12QSqlDatabase7driversEv 可用数据库插件驱动查看 "QSQLITE" "QODBC" "QODBC3" "QPSQL" "QPSQL7" pro文件添加&#xff1a; QTsql

VUE + SSM + ElementUI 图片上传失败,访问后台接口时报400错误

最近在做vue SSM 前后端分离项目的时候遇到了图片上传失败的错误。经过一番查询&#xff0c;发现问题如下&#xff1a; 后台无法解析MultipartFile&#xff0c;需要将该过程托管给Spring。 Springmvc中&#xff0c;文件上传通过MultipartResolver实现&#xff0c;故只需要在…

非首屏图片延时加载

目标 减少资源加载可以明显的优化页面加载的速度&#xff0c;所以可以减少页面载入时立即下载的图片的数量&#xff0c;以提高页面加载速度&#xff0c;其他的图片在需要的时候再进行加载。 思路 想要实现以上的目标&#xff0c;有几个地方需要思考。 1、如何判断哪些图片需要立…

现有版本的QT中可用数据库插件驱动查看

现有版本的QT中可用数据库插件驱动查看 #include <QCoreApplication> #include <QDebug> #include <QStringList> #include <QtSql/QSqlDatabase>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);qDebug()<<"现有版本的…