Yii2:在 ActiveRecord 中从连接的表获取额外字段

yii2:在 activerecord 中从连接的表获取额外字段

本文档介绍了在使用 Yii2 框架进行数据库查询时,如何通过 JOIN 操作从关联表中获取额外的字段,并将其作为 ActiveRecord 对象的一部分返回。重点解决了在执行 JOIN 查询后,额外字段在 ActiveRecord 对象中丢失的问题,并提供了明确的解决方案。

在使用 Yii2 的 ActiveRecord 进行数据库查询时,有时我们需要从关联的表中获取一些额外的信息。例如,我们有两个表 product_url 和 shop,它们通过 URL 进行关联,我们希望在查询 product_url 的同时,获取 shop 表中的 tag 字段。直接使用 JOIN 查询可能会导致额外字段丢失的问题,本教程将介绍如何解决这个问题。

问题描述

假设我们有以下两个表:

product_url

id product_id url
1 1234 https://www.php.cn/link/1aa4d17f2dcdae2f4ced909341741792
2 1234 https://www.php.cn/link/80577d9cb5c479e8e8b85252f1bfe005
3 1234 https://www.php.cn/link/e6ceb6cde9578ed6229ba2da69234a14
4 4321 https://www.php.cn/link/d9a11bb21bc9ba7d56e152baed4a3c9c

shop

id url tag
1 https://www.php.cn/link/e40cce862b0fb75635e102bc1dd07f6f low
2 https://www.php.cn/link/cd65710fc56d8163dfaed043e4129690 med
3 https://www.php.cn/link/2c09b237b3fe0a29b7ae5b63cd8632aa hig

我们希望通过以下查询,得到包含 tag 字段的 product_url 数据:

期望的 product_url_tag 结果

id product_id url tag
1 1234 https://www.php.cn/link/1aa4d17f2dcdae2f4ced909341741792 low
2 1234 https://www.php.cn/link/80577d9cb5c479e8e8b85252f1bfe005 med
3 1234 https://www.php.cn/link/e6ceb6cde9578ed6229ba2da69234a14 hig
4 4321 https://www.php.cn/link/d9a11bb21bc9ba7d56e152baed4a3c9c low

如果使用以下代码进行查询:

$product_url = ProductUrl::find()
    ->alias('pu')
    ->select('pu.*, tag')
    ->leftJoin('shop', "SUBSTRING_INDEX(pu.url, '/', 3) = SUBSTRING_INDEX(shop.url, '/', 3)")
    ->all();
登录后复制

我们会发现 tag 字段并没有出现在 ProductUrl 对象的属性中。

Fotor AI Image Upscaler

Fotor AI Image Upscaler

Fotor推出的AI图片放大工具

Fotor AI Image Upscaler48


查看详情
Fotor AI Image Upscaler

解决方案

解决这个问题的方法是在 ProductUrl 模型类中显式声明 tag 属性。

打开 ProductUrl.php 文件,添加以下代码:

namespace app/models;

use Yii;

/**
 * This is the model class for table "product_url".
 *
 * @property int $id
 * @property int $product_id
 * @property string $url
 *
 * @property Product $product
 * @property Shop $shop
 */
class ProductUrl extends /yii/db/ActiveRecord
{
    // 显式声明 tag 属性
    public $tag;

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'product_url';
    }

    // ... 其他代码 ...
}
登录后复制

解释:

通过 public $tag; 声明,我们告诉 Yii2 ProductUrl 模型有一个名为 tag 的属性。 这样,在执行 JOIN 查询时,Yii2 会将 shop 表中的 tag 字段的值赋给 ProductUrl 对象的 tag 属性。

现在,再次运行查询代码:

$product_url = ProductUrl::find()
    ->alias('pu')
    ->select('pu.*, tag')
    ->leftJoin('shop', "SUBSTRING_INDEX(pu.url, '/', 3) = SUBSTRING_INDEX(shop.url, '/', 3)")
    ->all();

foreach ($product_url as $product) {
    echo $product->url . ' - ' . $product->tag . '<br>';
}
登录后复制

你将会看到 tag 字段已经成功地被包含在 ProductUrl 对象中了。

注意事项

  • 字段映射: 确保 select() 方法中选择的字段名称与你在模型中声明的属性名称一致。
  • 模型类: 必须在对应的模型类中声明该属性,否则 Yii2 无法将查询结果映射到对象属性上。
  • 避免歧义: 如果连接的多个表中有相同的字段名,需要在 select() 方法中使用别名来区分它们,并在模型中定义对应的属性。

总结

通过在模型类中显式声明需要从 JOIN 查询中获取的额外字段,我们可以轻松地将这些字段作为 ActiveRecord 对象的一部分进行访问。这使得我们可以更方便地处理复杂的数据查询,并保持代码的整洁和可维护性。 这种方法避免了使用 asArray() 方法,从而可以利用 ActiveRecord 的所有优点,例如关联关系和行为。

以上就是Yii2:在 ActiveRecord 中从连接的表获取额外字段的详细内容,更多请关注php中文网其它相关文章!

https://www.php.cn/faq/1507438.html

发表回复

Your email address will not be published. Required fields are marked *