You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在加载产品时自动加载其关联的streams数据?

实现方案

你之前监听ProductEvents::PRODUCT_LOADED_EVENT的思路存在问题:该事件触发时,产品主表数据已经完成数据库查询、实体实例化流程,此时已经无法触发Doctrine的关联预加载逻辑,如果在事件回调中循环调用$product->getStreams(),会产生严重的N+1查询问题,产品数量较多时页面性能会大幅下降。
针对你需要的产品页、分类页场景,直接在产品查询的Criteria构建阶段添加上streams关联即可,底层会自动完成关联数据的联表预加载,后续直接调用$product->getStreams()就能拿到完整关联数据,无额外查询开销。

具体实现

创建事件订阅者,监听产品详情页、产品列表页的Criteria构建事件,统一添加streams关联:

<?php declare(strict_types=1);

namespace CustomPlugin\Subscriber;

use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductPageCriteriaEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ProductLoadSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            ProductPageCriteriaEvent::class => 'appendStreamsAssociation',
            ProductListingCriteriaEvent::class => 'appendStreamsAssociation',
        ];
    }

    public function appendStreamsAssociation(ProductPageCriteriaEvent|ProductListingCriteriaEvent $event): void
    {
        $event->getCriteria()->addAssociation('streams');
    }
}

给该订阅者正确配置服务标签(Shopware 6版本默认自动加载src/Subscriber目录下的订阅者,无需手动配置),清除缓存后即可生效,产品页、分类页加载产品时会自动关联查询streams数据,直接调用$product->getStreams()即可获取完整数据,不需要通过扩展属性中转。

扩展:全场景自动加载

如果你需要在所有产品加载场景(包括后台、API、第三方插件查询产品数据)都自动加载streams关联,不需要每次查询手动加关联,可以通过CompilerPass修改产品实体的Doctrine元数据定义,将streams关联的加载模式调整为EAGER,加载产品主表数据时会自动带上关联的streams数据。

注意:全场景EAGER加载会给所有产品相关的查询增加额外联表开销,非必要不推荐使用,优先使用定向页面加关联的方案。


内容的提问来源于stack exchange,提问作者Alphaegen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 05:18:20