gpt4 book ai didi

mysql - Yii2 通过联结表进行急切负载聚合

转载 作者:行者123 更新时间:2023-11-29 11:15:59 26 4
gpt4 key购买 nike

我有下表:

  • 内容 - ID (PK)、标题、...其他字段...
  • content_category - content_id (FK 到内容),category_id (FK 到内容)

一段内容有有多个个类别,而一个类别也是一段内容。

在内容中我有以下代码:

public function getCategories()
{
return $this
->hasMany(Category::className(), ['id' => 'category_id'])
->viaTable('content_category', ['content_id' => 'id']);
}

public function getCategoriesCsv(){
...
}

对于后端的 GridView ,我想为每段内容显示逗号分隔的类别列表。

我知道我可以单独选择此信息,但我希望将其作为查找查询的一部分,并在可能的情况下使用现有关系。

最佳答案

使用定义的关系(更简单,效率较低)。

这种方法是典型的方式,它适用于相关的Category模型。因此它需要大量的内存。

class Content extends \yii\db\ActiveRecord
{
/**
* Returns comma separated list of category titles using specified separator.
*
* @param string $separator
*
* @return string
*/
public function getCategoriesCsv($separator = ', ')
{
$titles = \yii\helpers\ArrayHelper::getColumn($this->categories, 'title');

return implode($separator, $titles);
}

// ...
}

应与预加载一起使用:

Content::find()
->with('categories')
->all();

使用子查询(效率更高,但不太方便)

此方法使用子查询,不使用关系和相关模型。因此这种方式速度更快并且保留大量内存。

class Content extends \yii\db\ActiveRecord
{

const ATTR_CATEGORIES_CSV = 'categoriesCsv';

/**
* @var string Comma separated list of category titles.
*/
public $categoriesCsv;

/**
* Returns DB expression for retrieving related category titles.
*
* @return \yii\db\Expression
*/
public function prepareRelatedCategoriesExpression()
{
// Build subquery that selects all category records related with current content row.
$queryRelatedCategories = Category::find()
->leftJoin('{{%content_category}}', '{{%content_category}}.[[category_id]] = {{%category}}.[[id]]')
->andWhere(new \yii\db\Expression('{{%content_category}}.[[content_id]] = {{%content}}.[[id]]'));

// Prepare subquery for retrieving only comma-separated titles
$queryRelatedCategories
->select(new \yii\db\Expression('GROUP_CONCAT( {{%category}}.[[title]] )'));

// Prepare expression with scalar value from subquery
$sqlRelatedCategories = $queryRelatedCategories->createCommand()->getRawSql();

return new \yii\db\Expression('(' . $sqlRelatedCategories . ')');
}

// ...
}

当附加列的别名等于某个模型属性时,它将由 all() 方法填充:

$contentModels = Content::find()
->andSelect([
'*',
Content::ATTR_CATEGORIES_CSV => Content::prepareRelatedCategoriesExpression(),
])
->all();


foreach ($contentModels as $contentModel) {
$contentModel->id;
$contentModel->categoriesCsv; // it will be also populated by ->all() method.
// ...
}

ps:我没有测试这段代码,可能应该是修复检索类别的查询。

此外,在这个示例中,它使用基本的简单语法编写,但可以使用各种帮助器、连接模型等将其优化为更可爱的状态。

关于mysql - Yii2 通过联结表进行急切负载聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39742819/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com