laravel 中关联关系数据是如何组装的。

laravel中 HasMany 一对多 通过with关联,会产生2条sql语句来避免N+1,但是laravel是如何组装这2条查询结果的。

是通过遍历根据ID来组装的,还是其他办法。请教一下大家。

  • 例如:
    {
      "id": 1,
      "label": "label1",
      "value": "value1",
      "child": {
          [
              "id": 3,
              "parent_id": 1,
              "label": "label1-1",
              "value": "value1-1",
              "child": {
                  "id": 4,
                  "parent_id": 3,
                  "label": "label1-1-1",
                   "value": "value1-1-1",
              }
          ],
          [
              "id": 5,
              "parent_id": 6,
              "label": "label1-2",
              "value": "value1-2"
              "child": {
                  "id": 7,
                  "parent_id": 5,
                  "label": "label1-2-1",
                   "value": "value1-2-1",
              }
          ]
     }
    }
    

```

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 7

根据id和子表parent_id,组装sql,将查询到的数据再根据关联关系附加到数据中去

例如你的数据 select * from table where parent_id in (1)得到的数据在放到list上面去

1年前 评论
西巴以及 (楼主) 1年前

通过关联方法的 match 方法来进行匹配的,比如前面的 HasMany。

是从查询构建器的 get -> eagerLoadRelations -> eagerLoadRelation

1年前 评论
西巴以及 (楼主) 1年前
Rache1 (作者) 1年前

临下班了, 特地帮你把源码翻出来,就是foreach

namespace Illuminate\Database\Eloquent\Relations;

abstract class HasOneOrMany extends Relation
{
    /**
     * Match the eagerly loaded results to their many parents.
     *
     * @param  array  $models
     * @param  \Illuminate\Database\Eloquent\Collection  $results
     * @param  string  $relation
     * @param  string  $type
     * @return array
     */
    protected function matchOneOrMany(array $models, Collection $results, $relation, $type)
    {
        $dictionary = $this->buildDictionary($results);

        // Once we have the dictionary we can simply spin through the parent models to
        // link them up with their children using the keyed dictionary to make the
        // matching very convenient and easy work. Then we'll just return them.
        foreach ($models as $model) {
            if (isset($dictionary[$key = $this->getDictionaryKey($model->getAttribute($this->localKey))])) {
                $model->setRelation(
                    $relation, $this->getRelationValue($dictionary, $key, $type)
                );
            }
        }

        return $models;
    }
}
1年前 评论
西巴以及 (楼主) 1年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!