Symfony findOneBy:列类型数组返回null

时间:2017-07-06 08:59:00

标签: php mysql symfony doctrine

我有一个带有列类型数组的实体

/**
 * Report entity
 *
 * @ORM\Table(name="report")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\ReportRepository")
 */
class Report
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var array
     *
     * @ORM\Column(name="selectedCountries", type="array", nullable=true)
     */
    private $selectedCountries;

在数据库中,我有一条记录,存储为:

+-------------------------+
|    selectedCountries    |
+-------------------------+
|         a:0:{}          |
+-------------------------+

当我这样做时:

$report = $this->reportRepository->findOneBy(array('selectedCountries' => []));

我得到了null,我不明白为什么。

数据库连接,实体,存储库等工作正常:当我在findOneBy()中包含此数组时,它找不到结果。

1 个答案:

答案 0 :(得分:1)

Symfony profiler的帮助下,我调试了doctrine制作的查询,发现我需要使用simple_array而不是array作为@ORM\Column type

当我使用数组作为列类型时:doctrine会在将数据保存到数据库时序列化此数组,如a:0:{}。这种方法的问题是当我尝试运行findby时:

  • 如果我使用数组作为参数,则doctrine querie如下所示:..AND t0.selectedCountries IN ('de')..
  • 如果我使用序列化数组,则doctrine会像这样逃避它:..AND t0.selectedCountries = 's:19:\"a:1:{i:0;s:2:\"de\";}\";' ..

所以在这两种情况下都找不到记录!

但是使用simple_array doctrine查询看起来像:.. AND t0.selectedCountries IN ('de') ..这是完美的,因为表中的数据现在保存为:

+-------------------------+
|    selectedCountries    |
+-------------------------+
|         de              |
+-------------------------+

此方法的唯一问题是当您在数组中有更多元素时:selectedCountries => de,fr,uk并希望按此搜索。要做到这一点,你应该做额外的工作:

@ORM\HasLifecycleCallbacks()添加到您的实体并在插入

之前对数组进行排序
/**
 * @ORM\PrePersist
 */
public function setSelectedCountriesValue()
{
    sort($this->selectedCountries);
}

在您的实体的存储库中使用Query Builder并在尝试查找结果时对数组进行排序。

 $qb = $this->getEntityManager()->createQueryBuilder();

        $qb->select('r')
            ->from('AppBundle:Report', 'r')
            ...

        if ($creteria['selectedCountries']) {
            sort($creteria['selectedCountries']);
            $qb->andWhere('r.selectedCountries= :selectedCountries')
                ->setParameter('selectedCountries', implode(',', $creteria['selectedCountries']));
        }
相关问题