我有一个存储库函数,可根据类别检索随机产品。我正在使用APC缓存仅在缓存过期时缓存结果和随机产品。一切都很好,除了产品的图像没有保存在缓存中。 产品实体与ProductImages实体具有OneToMany关系,如下所示:
/**
* @var arrayCollection
*
* @ORM\OneToMany(targetEntity="ProductImage", mappedBy="product", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $images;
public function __construct()
{
$this->images = new ArrayCollection();
}
/**
* @var Product
*
* @ORM\ManyToOne(targetEntity="Product", inversedBy="images")
* @ORM\JoinColumn(name="product_id", referencedColumnName="id")
*/
private $product;
我的存储库功能:
/**
* @param $category
* @param $limit
* @param $source
* @param $cacheExpiresTime
* @return \Doctrine\ORM\Query
*/
public function findByCategoryLimit($category, $limit, $source, $cacheExpiresTime = 3600)
{
$cacheDriver = new ApcCache();
$cacheId = 'category_'.$category->getId().'_products';
$config = $this->getEntityManager()->getConfiguration();
$config->setResultCacheImpl($cacheDriver);
if ($config->getResultCacheImpl()->contains($cacheId))
{
return $config->getResultCacheImpl()->fetch($cacheId);
}
$qb = $this->createQueryBuilder('p');
$qb->select('p')
->leftJoin('p.sourceCategory', 's')
->where('s.category = :category')
->setMaxResults($limit)
->setParameter('category', $category);
if (!empty($source)){
$qb->andWhere('p.source = :source');
$qb->setParameter('source', $source);
}
$qb->orderBy('p.title', 'ASC');
if($this->getCategoryTotalProducts($category) > $limit) {
$qb->setFirstResult(rand(1, ($this->getCategoryTotalProducts($category) - $limit)));
}
$query = $qb->getQuery();
//$query->setResultCacheDriver($cacheDriver);
//$query->useResultCache(true, $cacheExpiresTime, $cacheId);
$result = $query->getResult();
$config->getResultCacheImpl()->save($cacheId, $result, $cacheExpiresTime);
return $result;
}
当从db加载产品时,图像看起来很好但是当从缓存加载时图像消失(空)。我在这里做错了什么?我尝试了不同的方法,并寻找一个没有成功的解决方案。 $ cacheExpiresTime设置为20
提前致谢。
答案 0 :(得分:0)
您是否尝试过加载图片? (添加连接并选择查询)。这是我知道的解决方法:)
答案 1 :(得分:0)
问题是查询偏移量。 这是解决方案。现在它按预期工作。
/**
* @param $category
* @param $limit
* @param $source
* @param $cacheExpiresTime
* @return \Doctrine\ORM\Query
*/
public function findByCategoryLimit($category, $limit, $source, $cacheExpiresTime = 3600)
{
$cacheDriver = new ApcCache();
$cacheId = 'category_'.$category->getId().'_products';
$config = $this->getEntityManager()->getConfiguration();
$config->setResultCacheImpl($cacheDriver);
$offset = 0;
if($this->getCategoryTotalProducts($category) > $limit) {
$offset = rand(1, ($this->getCategoryTotalProducts($category) - $limit));
}
if ($config->getResultCacheImpl()->contains($cacheId))
{
$offset = $config->getResultCacheImpl()->fetch($cacheId);
}
$qb = $this->createQueryBuilder('p');
$qb->select('p')
->leftJoin('p.sourceCategory', 's')
->where('s.category = :category')
->setMaxResults($limit)
->setParameter('category', $category);
if (!empty($source)){
$qb->andWhere('p.source = :source');
$qb->setParameter('source', $source);
}
$qb->orderBy('p.title', 'ASC');
$qb->setFirstResult($offset);
$query = $qb->getQuery();
$query->useQueryCache(true);
$query->useResultCache(true);
$result = $query->getResult();
if (!$config->getResultCacheImpl()->contains($cacheId)) {
$config->getResultCacheImpl()->save($cacheId, $offset, $cacheExpiresTime);
}
return $result;
}