使用Doctrine进行Symfony查询

时间:2017-11-30 19:07:41

标签: symfony doctrine

我正在努力通过Symfony 3来改善自己。我在构建查询时遇到错误,以获得与应用程序无关且日期超过30天的广告。

我在我的控制器中创建了一个新方法,在我的advertRepository中创建了一个新查询,在一个名为“Purger”的服务中我必须删除这些旧广告。

我粘贴下面的代码(控制器,服务类,AdvertRepository,services.yml):

public function purgeAction($days) 
{
  // Appel du service
  $testPurge = $this->get('oc_platform.purger.advert');
  $testPurge->purge($days);

  return new Response("Purge done !");
}

namespace OC\PlatformBundle\Purger\Advert;

use OC\PlatformBundle\Entity\Advert;
use Doctrine\ORM\EntityManager;

class OCAdvertsPurger 
 {
  private $em;

  public function __construct(EntityManager $em)
  {
    $this->em = $em;
  }

  //Ce service va récupérer et supprimer toutes les annonces dont la date de 
  modification
  // est plus vieille que X jours. Ce "X" est le paramètre de la méthode.
  public function purge($days)
   {
     $listAdverts = $this->em->getRepository('OCPlatformBundle:Advert')-
     >getOldAdvertsOnly($days);
   }
 }


public function getOldAdvertsOnly($days)
{
  // Liste de toutes les annonces
  $qb = $this->createQueryBuilder('a')
    ->leftJoin('a.applications', "app")
    ->addSelect('app')
  ;

  // On retire celles attachées à des candidatures
  $qb->where($qb->expr()->isNull('app.advert_id'));

  return $qb
    ->getQuery()
    ->getResult()
  ;
}

public function deleteOldAdvertsOnly($adverts)
{ 
  $qb = $this->createQuery('DELETE $adverts FROM 
  OC\PlatformBundle\Entity\Advert  WHERE DATE_DIFF(CURRENT_DATE(), 
  updated_at) > $days');

  return $qb
    ->getQuery()
    ->getResut()
  ;
}
    services:
        oc_platform.purger.advert:
        class: OC\PlatformBundle\Purger\Advert\OCAdvertsPurger
        arguments: 
            - "@doctrine.orm.entity_manager"

我尝试使用queryBuilder在同一个查询中使用DATE_DIFF函数()执行某些操作,但是由于queryBuilder()不知道此函数为CURRENT_DATE(),我认为所以我试图让它与两个不同的查询(一个使用queryBuilder,另一个使用DQL语言)。

非常感谢能帮助我!

3 个答案:

答案 0 :(得分:0)

我认为你可以只在一个查询中执行此操作。看起来像这样:

$dateThreshold = new \DateTime();
$dateThreshold->modify("-30 days");
$qb = $this->createQueryBuilder('add')
    ->delete('add')
    ->where("add.app_id IS NULL")
    ->andWhere("add.updated_at <= :date_threshold")
    ->setParameter("date_threshold", $dateThreshold)
    ->getQuery()->execute()

我不熟悉你的数据库结构,但你应该从上面的例子中得到一个想法。

答案 1 :(得分:0)

要使用DATEDIFF功能(或任何其他功能),您必须安装Doctrine Extension:

composer require beberlei/DoctrineExtensionshttps://github.com/beberlei/DoctrineExtensions

并在你的config.yml:

orm:
 entity_managers:
  default:
    dql:
      datetime_functions:
        DateDiff: DoctrineExtensions\Query\Mysql\DateDiff

现在,您可以像在SQL中一样在查询构建器中使用DATEDIFF。

可用的功能:

MySQL:

ACOS, AES_DECRYPT, AES_ENCRYPT, ANY_VALUE, ASCII, ASIN, ATAN, ATAN2, BINARY, BIT_COUNT, BIT_XOR, CEIL, CHAR_LENGTH, COLLATE, CONCAT_WS, CONVERT_TZ, COS, COT, COUNTIF, CRC32, DATE, DATE_FORMAT, DATEADD, DATEDIFF, DATESUB, DAY, DAYNAME, DAYOFWEEK, DAYOFYEAR, DEGREES, DIV, EXP, EXTRACT, FIELD, FIND_IN_SET, FLOOR, FROM_UNIXTIME, GREATEST, GROUP_CONCAT, HEX, HOUR, IFELSE, IFNULL, LAST_DAY, LEAST, LOG, LOG10, LOG2, LPAD, MATCH, MD5, MINUTE, MONTH, MONTHNAME, NOW, NULLIF, PI, POWER, QUARTER, RADIANS, RAND, REGEXP, REPLACE, ROUND, RPAD, SECOND, SECTOTIME, SHA1, SHA2, SIN, SOUNDEX, STD, STDDEV, STRTODATE, STR_TO_DATE, SUBSTRING_INDEX, TAN, TIME, TIMEDIFF, TIMESTAMPADD, TIMESTAMPDIFF, TIMETOSEC, UNHEX, UNIX_TIMESTAMP, UTC_TIMESTAMP, UUID_SHORT, VARIANCE, WEEK, WEEKDAY, YEAR, YEARWEEK

的Oracle

DAY, LISTAGG, MONTH, NVL, TO_CHAR, TO_DATE, TRUNC, YEAR

SQLite的

DATE, MINUTE, HOUR, DAY, WEEK, WEEKDAY, MONTH, YEAR, STRFTIME, DATE_FORMAT*, CASE WHEN THEN ELSE END, IFNULL, REPLACE, ROUND

的PostgreSQL

TO_DATE, TO_CHAR, AT_TIME_ZONE, COUNT_FILTER, STRING_AGG

答案 2 :(得分:0)

谢谢你们!我只是修改了我的查询,它工作了! 我必须记住你向Doctrine添加SQL函数的技巧:)