symfony – 教义2:一对多关联缓存

栏目: PHP · 发布时间: 6年前

内容简介:http://stackoverflow.com/questions/36978702/doctrine-2-cache-in-one-to-many-associations

我正在尝试使用通用软件包中的教条缓存,但是我无法使用一对多,多对一的注册.我稍后会解释一下我要做的事情.

我的配置:

'configuration' => array(
    'orm_default' => array(
        'metadata_cache'    => 'filesystem',
        'query_cache'       => 'filesystem',
        'result_cache'      => 'filesystem',
        'hydration_cache'   => 'filesystem',
    )
),

我的实体

class Category
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     *
     * @var string
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=100, nullable=false)
     */
    protected  $name;

    /**
     * @var integer
     *
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="childrenId", fetch="EAGER")
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id")
     */
    protected $parentId;


    /**
     * @ORM\OneToMany(targetEntity="Category", mappedBy="parentId", fetch="EAGER")
     */
    protected $childrenId;
}

我的DQL

$result = $this->em->createQueryBuilder()->select('c')
    ->from('App\Entity\Category', 'c')
    ->where('c.parentId IS NULL')
    ->orderBy('c.priority', 'ASC')
    ->getQuery()
    ->setFetchMode("App\Entity\Category", "parentId", \Doctrine\ORM\Mapping\ClassMetadata::FETCH_EAGER);
    ->useResultCache(true, 900, 'categories')
    ->getResult();

我有28个类别,其中15个有parentId.

以上查询执行29个 SQL 查询,但Doctrine仅存储在缓存中1,所以当我再次运行这个查询时,它执行28个查询.

任何想法我做错了什么?缺少一些缓存配置?在DQL中缺少一些方法?我想缓存所有查询不仅仅是一个主要的查询.

编辑

我想在循环中使用查询结果,如下所示:

foreach($result as $row)
{
    $categories[]['attr'] = $row->getAttribute()->getName();
    $categories[]['value'] = $row->getAttribute()->getValue();
}

但是这种方式缓存将无法正常工作,所以目前我正在使用:

foreach($result as $row)
{
        $attributes = $this->em->createQueryBuilder()->select('c, a.name, a.value')
            ->from('App\Entity\Category', 'c')
            ->innerJoin('App\Entity\Attribute', 'a', 'WITH', 'a.id = c.attribute')
            ->where('c.id = :catId')
            ->setParameter('catId', $row['id'])
            ->getQuery()
            ->useResultCache(true, 900, $categoryName.'-attributes')
            ->getArrayResult();
}

但是我宁愿在数组上处理对象,但是如果我使用对象并且它具有关联,那么这个关联将不会被缓存.所以理想的方法是缓存对象ALL他的关联.

关联提取模式

您所提供的查询只能提取“父类”类别实体,该实体可以通过未初始化的子项来收集.当访问该集合(通过迭代这些孩子)时,Doctrine将加载集合,从而执行另一个查询.它会对第一个查询所包含的所有父类别执行此操作.

将提取模式设置为EAGER只会更改这些查询完成的时刻.教义将在保持父类别之后立即执行,直到您访问该集合才能等待(如使用提取模式LAZY).但它仍然会执行这些查询.

获取连接查询

告诉Doctrine与孩子查询和合并类别的最简单的方法是做一个“fetch join”查询:

$queryBuilder = $this->em->createQueryBuilder();
$queryBuilder
    ->select('p', 'c') // [p]arent, [c]hild
    ->from('App\Entity\Category', 'p')
    ->leftJoin('p.children', 'c')
    ->where('p.parent IS NULL')
    ->orderBy('p.priority', 'ASC');

$query = $queryBuilder->getQuery();
$query
    ->useResultCache(true, 900, 'categories')

$result = $query->getResult();

请注意这里的select()和leftJoin()调用.

您也不需要更改关联的提取模式(通过调用setFetchMode()),因为查询本身会告诉Doctrine来执行所需的操作.

这样做的结果是,如果Doctrine尚未缓存(或缓存为陈旧),则Doctrine将执行1个查询,如果缓存(仍然是新鲜的),则会执行0个查询.

假设

属性$parentId(在类别中)被重命名为$parent.此属性将包含父类别实体,或null,但不包含id.

$childrenId的属性重命名为$children.此属性将包含一个类别实体(可能为空)的集合,但不包含ids的集合(或数组),并且绝对不会有一个id.

我上面提出的查询考虑了这些重命名.

我完全忽略了一个事实,即你的“编辑”一个新的属性实体刚刚成立.这与你的问题无关,或者这个答案是呃.

更多的水平

看起来/听起来像你的类别只使用2级(父母和孩子).当您引进更多级别(孙子等)时,阅读此模型可能会非常低效.

当进行3级或更多级别时,您可能需要查看 Nested Set model .写入次数较重,但对读取进行了高度优化.

DoctrineExtensions 图书馆支持这一点,还有一个 Symfony Bundle .

http://stackoverflow.com/questions/36978702/doctrine-2-cache-in-one-to-many-associations


以上所述就是小编给大家介绍的《symfony – 教义2:一对多关联缓存》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

企业应用架构模式

企业应用架构模式

Martin Fowler、王怀民、周斌 / 王怀民、周斌 / 机械工业出版社 / 2004-7 / 49.00元

本书作者是当今面向对象软件开发的权威,他在一组专家级合作者的帮助下,将40多种经常出现的解决方案转化成模式,最终写成这本能够应用于任何一种企业应用平台的、关于解决方案的、不可或缺的手册。本书获得了2003年度美国软件开发杂志图书类的生产效率奖和读者选择奖。本书分为两大部分。第一部分是关于如何开发企业应用的简单介绍。第二部分是本书的主体,是关于模式的详细参考手册,每个模式都给出使用方法和实现信息,并一起来看看 《企业应用架构模式》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具