【问题标题】:How to get the raw query from EntityRepository from the controller如何从控制器的 EntityRepository 获取原始查询
【发布时间】:2014-06-10 19:20:36
【问题描述】:

我需要将原始查询作为字符串获取,类似这样。

$query = 'SELECT p FROM GabrielUploadBundle:Image p WHERE p.upvotes > x ORDER BY p.createdAt ASC';

我的自定义“findAllNewestByVotes”方法包含查询。

class ImageRepository extends EntityRepository
{
    public function findAllNewestByVotes($maxvotes)
    {
        return $this->getEntityManager()
        ->createQuery(
            'SELECT p FROM GabrielUploadBundle:Image p WHERE p.upvotes > '.$maxvotes.' ORDER BY p.createdAt ASC')
        ->getResult();
    }

}
/**
 * @Route("/world/front",name="world-front")
 * @Template()
 */
public function indexAction()
{
    $images = $this->get('doctrine')->getRepository('GabrielUploadBundle:Image')->findAllNewestByVotes(50);

    ladybug_dump($images);
    return $this->render('GabrielLayoutBundle:Worldpage:index.html.twig',array('images'=>$images));
}

我需要的是类似的东西 $images->getRawQuery() // 以字符串形式返回查询


解决方案(参考最佳答案)

    /**
     * ImageRepository
     *
     * This class was generated by the Doctrine ORM. Add your own custom
     * repository methods below.
     */
    class ImageRepository extends EntityRepository
    {
        public function findAllNewestByVotes($maxvotes)
        {
            return $this->getEntityManager()
            ->createQuery(
                'SELECT p FROM GabrielUploadBundle:Image p WHERE p.upvotes > '.$maxvotes.' ORDER BY p.createdAt ASC');
        } 
    }

> create image repository

    $images = $this->get('doctrine')->getRepository('GabrielUploadBundle:Image')->findAllNewestByVotes(50);
 return the raw query as string like this
    $images->getDQL()
 return objects like this
    $images->getResult();

【问题讨论】:

  • 作为字符串的查询是毫无用处的,除非你考虑将它作为一个丑陋的字符串附加到它上面,因为 Doctrine 在动态构建 SQL 查询方面具有非常易于使用的功能。
  • 如果没有用,他们就不会创建 getDQL() 方法(见答案)
  • 它对你和我——图书馆的受益者/用户——没用——它对较低级别的工作很有用。
  • 也许适合你,但我需要将 getDQL() 方法传递给用于分页的捆绑包
  • 这是一个较低级别的集成。 3rd 方捆绑包需要 DQL 真是太愚蠢了……如果他们可以直接使用对象并且他们可以自己从对象中获取字符串,为什么还需要字符串?

标签: symfony doctrine-orm dql doctrine-query


【解决方案1】:

可以使用以下方法检索原始查询:

$this->getEntityManager()
    ->createQuery('
        SELECT p
            FROM GabrielUploadBundle:Image p
            WHERE p.upvotes > '.$maxvotes.'
            ORDER BY p.createdAt ASC
    ')
    ->getSQL();

但这是一个简单的查询,为什么不使用 DQL 并单独添加参数(使用可避免 SQL 注入攻击的准备好的语句)?

$this->getEntityManager()
    ->createQueryBuilder()

    ->select('p')
    ->from('GabrielUploadBundle:Image')

    ->where('p.upvotes > :maxvotes')
    ->setParameter('maxvotes', $maxvotes)

    ->orderBy('p.createdAt', 'ASC')

    ->getSQL();

为了能够从控制器获取查询(对象)或查询构建器(对象),您需要将存储库逻辑分解为 2 个函数,一个用于构建查询,另一个用于使用参数调用查询:

class ImageRepository extends EntityRepository
{
    public function findAllNewestByVotesQuery($maxvotes)
    {
        return $this->getEntityManager()
            ->createQueryBuilder()

            ->select('p')
            ->from('GabrielUploadBundle:Image')

            ->where('p.upvotes > :maxvotes')
            ->setParameter('maxvotes', $maxvotes)

            ->orderBy('p.createdAt', 'ASC');
    }

    public function findAllNewestByVotes($maxvotes)
    {
        return $this
            ->findAllNewestByVotesQuery($maxvotes)
            ->getQuery()
            ->getResult();
    }
}

【讨论】:

  • 有没有办法从控制器中获取它,而不必为每个控制器重新键入字符串?在这种情况下像 $image->getSQL() 什么的?
  • 把它分成两个函数——一个构建查询,一个调用它。您应该在您拥有的每个存储库中都这样做,这样您就可以轻松地更改查询,而无需复制粘贴代码。
  • 我没有看到编辑请求——如果有的话我会接受的。或者,如果您会在评论等中向我指出评论......
  • 我正在审查编辑请求,但它完全用你的回答代替了我的回答。当问题是导致无限递归的函数名称拼写错误时。
  • 我更正了函数名称以调用查询构建器函数。
猜你喜欢
  • 2018-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 2012-09-21
  • 2021-10-12
  • 2017-10-09
相关资源
最近更新 更多