QueryBuilder连接日期和时间

时间:2014-10-25 00:56:48

标签: symfony doctrine-orm

我想找到两个日期之间的冲突。问题是在数据库中我单独日期和时间字段。所以我做了concat(日期,时间):

public function findConflictingEvents($datef,$dateu,$personID){
    $from = $datef->format('Y-m-d H:i:s');
    $until = $dateu->format('Y-m-d H:i:s');

    $qb = $this->createQueryBuilder('event');
    $qb->select('event')
        ->innerJoin('event.visitors', 'p')
        ->add('where',
            $qb->expr()->orX(
                $qb->expr()->andX(
                    $qb->expr()->lte(':until', $qb->expr()->concat('event.date_until', 
                        $qb->expr()->literal(' '), 'event.time_until')),
                    $qb->expr()->gte(':until', $qb->expr()->concat('event.date_from', 
                        $qb->expr()->literal(' '), 'event.time_from'))
                ),
                $qb->expr()->andX(
                    $qb->expr()->lte(':from', $qb->expr()->concat('event.date_until',
                        $qb->expr()->literal(' '), 'event.time_until')),
                    $qb->expr()->gte(':from', $qb->expr()->concat('event.date_from', 
                        $qb->expr()->literal(' '), 'event.time_from'))
                ),
                $qb->expr()->andX(
                    $qb->expr()->lte(':from', $qb->expr()->concat('event.date_from', 
                        $qb->expr()->literal(' '), 'event.time_from')),
                    $qb->expr()->gte(':until', $qb->expr()->concat('event.date_until', 
                        $qb->expr()->literal(' '), 'event.time_until'))
                )
            )                
        )
        ->andWhere('p.id = ?1')
        ->setParameter('from', $from)
        ->setParameter('until', $until)
        ->setParameter(1, $personID);
     return $qb->getQuery()->getResult();
}

但查询会产生意外结果。我认为我应该转换为时间戳并进行比较。

  • 如何在doctrine2 querybuilder中将日期和时间转换为unix_timestamp?
  • 或者还有其他想法怎么做?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

绑定参数和检查日期时间范围的表达式分配错误。连接也需要两个参数,你需要再次使用它作为第三部分。

此外,在使用Doctrine时,最好将数据库视为对象而不是表。尽可能使用对象。返回一个新的ArrayCollection而不是一个数组,并允许您的存储库方法接受Person的实例并从那里获取ID。

use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;

use Your\Bundle\Entity\Event;
use Your\Bundle\Entity\Person;

class EventRepository extends EntityRepository
{
    /**
     * @param \DateTime $from
     * @param \DateTime $until
     * @param Person    $person
     *
     * @return Event[]|Collection
     */
    public function findConflictingEvents(\DateTime $from, \DateTime $until, Person $person)
    {
        $qb = $this->createQueryBuilder('event');
        $qb->select('event')
            ->innerJoin('event.visitors', 'p')
            ->add('where',
                $qb->expr()->orX(
                    $qb->expr()->andX(
                        $qb->expr()->lte(
                            $this->buildDateTimeUntilExpression($qb),
                            ':until'
                        ),
                        $qb->expr()->gte(
                            $this->buildDateTimeFromExpression($qb),
                            ':until'
                        )
                    ),
                    $qb->expr()->andX(
                        $qb->expr()->lte(
                            $this->buildDateTimeUntilExpression($qb),
                            ':from'
                        ),
                        $qb->expr()->gte(
                            $this->buildDateTimeFromExpression($qb),
                            ':from'
                        )
                    ),
                    $qb->expr()->andX(
                        $qb->expr()->lte(
                            $this->buildDateTimeFromExpression($qb),
                            ':from'
                        ),
                        $qb->expr()->gte(
                            $this->buildDateTimeUntilExpression($qb),
                            ':until'
                        )
                    )
                )
            )
            ->andWhere('p.id = ?1')
            ->setParameter('from', $from)
            ->setParameter('until', $until)
            ->setParameter(1, $person->getId());
        ;

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

    /**
     * @param QueryBuilder $qb
     *
     * @return mixed
     */
    private function buildDateTimeUntilExpression(QueryBuilder $qb)
    {
        return $qb->expr()->concat('event.dateUntil', $qb->expr()->concat($qb->expr()->literal(' '), 'event.timeUntil'));
    }

    /**
     * @param QueryBuilder $qb
     *
     * @return mixed
     */
    private function buildDateTimeFromExpression(QueryBuilder $qb)
    {
        return $qb->expr()->concat('event.dateFrom', $qb->expr()->concat($qb->expr()->literal(' '), 'event.timeFrom'));
    }

}