热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

laravel多对多关联,明确定义出关联关系,自定义两表与关联表的关联字段

laravel的官方文档上面只介绍了belongsToMany的4个参数,文档如下:到这里为止,官方文档上面对于多对多关联介绍差不多完了&

laravel的官方文档上面只介绍了belongsToMany的4个参数,文档如下:




 到这里为止,官方文档上面对于多对多关联介绍差不多完了,如果想查看更多请看官方文档。


下面我来介绍在我们遇到两个表进行多对多关联,而且关联的时候,设置这两个表与中间表的关联字段。

例如:

    a表结构为:

        id 主键,

        tag 标识,

        …………

    b表结构为:

        id 主键,

        …………

    a_b表结构为:

        id 主键,

        b_id,

        a_tag

  当我们遇到这种情况的时候,查看官方文档上并没有找到相关的处理方法,官方文档上面的介绍整体说下来 :

    belongsToMany(关联表模型,中间表表名,中间表与当前模型的关联字段,中间表与关联表的关联字段);

    如果我们上面的表结构按照这种方式关联,假设我们当前模型为a ;  那么关联写为 belongsToMany(b:class, 'a_b', 'a_tag', 'b_id');

 如果我们这么写的话,产生出来的sql为:

    select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.id;

这样问题就出现了,我们实际上想要的sql语句为:

    select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.tag;

但是,我们应该怎么做才可以得到这样的结果呢?

    那就需要看下关于belongsToMany()的第四、第五个参数了;

    我先贴上laravel源码:

public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null,$parentKey = null, $relatedKey = null, $relation = null){// If no relationship name was passed, we will pull backtraces to get the// name of the calling function. We will use that function name as the// title of this relation since that is a great convention to apply.if (is_null($relation)) {$relation = $this->guessBelongsToManyRelation();}// First, we'll need to determine the foreign key and "other key" for the// relationship. Once we have determined the keys we'll make the query// instances as well as the relationship instances we need for this.$instance = $this->newRelatedInstance($related);$foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey();$relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey();// If no table name was provided, we can guess it by concatenating the two// models using underscores in alphabetical order. The two model names// are transformed to snake case from their default CamelCase also.if (is_null($table)) {$table = $this->joiningTable($related);}return $this->newBelongsToMany($instance->newQuery(), $this, $table, $foreignPivotKey,$relatedPivotKey, $parentKey ?: $this->getKeyName(),$relatedKey ?: $instance->getKeyName(), $relation);上面是源码,我们主要看

return $this->newBelongsToMany($instance->newQuery(), $this, $table, $foreignPivotKey,$relatedPivotKey, $parentKey ?: $this->getKeyName(),$relatedKey ?: $instance->getKeyName(), $relation);

我们看了上面的代码后明确知道了,belongsToMany()有7个参数,我们通过官方文档已经知道了前四个参数的作用,剩下两个参数只能我们自己通过源码来研究

$instance->newQuery(),$this, $table, $foreignPivotKey

返回值中的这几个参数我就不多做描述了,我主要描述:

$relatedPivotKey, $parentKey ?: $this->getKeyName(),$relatedKey ?: $instance->getKeyName()

这两个,也就是belongsToMany的第5、6个参数

第五个参数,我看了他的主要功能为判断是否传入该参数如果没有传入这个参数就去调用getKeyName(); 有的人要问了getKeyName()是干什么的呢?我也想问,然后我就继续查看了geiKeyName()的源码。这个方法是Model类的一个方法,用来获取表主键的.这仅仅说了getKeyName()方法,不是还有个$this没有说它到底指向的谁?它指向的是当前调用belongsToMany()的模型。

第六个参数与第五个参数作用是一样的,只是获取的模型不同而已。这个参数获取的是关联表的主键.


参数讲完了,我们传入后会得到什么样的sql呢?

belongsToMany(b:class,  'a_b',  'a_tag',  'b_id', 'tag', 'id');

下面我们就来看看到底会得到怎样的sql:

    select * from b inner join a_b on b.id = a_b.id where a_b.a_tag = a.tag ; 这就是我们得到的sql;

仔细看看,是不是和我们上面想要得到的sql语句一样?



推荐阅读
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
author-avatar
feng2502863897
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有