【问题标题】:Can I specify default conditions in Doctrine queries?我可以在 Doctrine 查询中指定默认条件吗?
【发布时间】:2019-02-14 05:23:42
【问题描述】:

我定义了一个基本的 Doctrine 页面实体。

namespace Example\Entity;

/**
 * @ORM\Entity
 */
class Page
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $title;

    /**
     * @ORM\Column(type="string", length=25)
     */
    private $status;
}

$status 属性将是“已发布”、“草稿”、“已删除”、“待定”之一。

我想知道这个实体上的所有查询是否可以自动包含条件WHERE status = 'published',除非查询另有说明。

此实体上 90% 的查询将针对已发布的帖子,开发人员很容易无意中抓取所有草稿、待处理和已删除的帖子,却没有意识到它们应该限制结果。

据我所知,Doctrine 的事件监听器仅适用于数据操作而不是选择。

【问题讨论】:

    标签: php symfony doctrine


    【解决方案1】:

    我认为这是不可能的,更简单的解决方案是为实体添加自定义存储库

    namespace Example\Entity;
    
    /**
     * @ORM\Entity(repositoryClass="Example\Entity\PageRepository")
     */
    class Page
    

    然后你可以创建新的方法,例如:

    class PageRepository extends EntityRepository
    {
        public function getAllPage()
            {
                return $this->_em->createQuery('SELECT p FROM Example\Entity\Page p WHERE u.status = "published"')->getResult();
            }
    }
    

    或者您可以覆盖存储库的默认方法并添加您的 where 条件。

    文档: http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html#custom-repositories

    【讨论】:

      【解决方案2】:

      我最近遇到了这样的任务并像这样解决了它(但我不认为这是 symfony 的方式:)): 创建了一个扩展 EntityREpository 的类:

      class MainPageRepository extends EntityRepository
      {
          protected function createQuery()
          {
              $queryBuilder = $this->getEntityManager()->createQueryBuilder();
              $query = $queryBuilder
                  ->select(array('p'))
                  ->from('STMainSiteWebBundle:Page', 'p')
                  ->where('p.deleted = :deleted')
                  ->setParameter('deleted', false);
      
              return $query;
          }
      }
      

      并在需要创建查询时对其进行扩展:

      class PageRepository extends MainPageRepository
      {
          public function fetchAllByType($type, $offset = 0, $limit = 15)
          {
              $query = $this->createQuery();
              $query
                  ->andWhere('p.pageType = :pageType')
                  ->orderBy('p.id', 'DESC')
                  ->setParameter('pageType', $type)
                  ->getQuery()
              ;
      
              $query->setFirstResult($offset);
              $query->setMaxResults($limit);
      
              return $query->getResult();
          }
      }
      

      【讨论】:

        【解决方案3】:

        你可以利用特质:

        trait WithStatus
        {
            public function createQueryBuilder($alias, $indexBy = NULL)
            {
                $qb = parent::createQueryBuilder($alias, $indexBy);
                $qb->where("$alias.status = :status");
                $qb->setParameter('status', 'published');
                return $qb;
            }
        }
        
        class PageRepository extends EntityRepository
        {
            use WithStatus;
        }
        

        【讨论】:

        • 我喜欢这个,但问题是,where 将被外部的新 where 覆盖。
        猜你喜欢
        • 1970-01-01
        • 2016-04-10
        • 2017-03-09
        • 1970-01-01
        • 2016-06-10
        • 1970-01-01
        • 2011-05-26
        • 1970-01-01
        • 2020-08-25
        相关资源
        最近更新 更多