我有一个带有列类型数组的实体
/**
* 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()中包含此数组时,它找不到结果。
答案 0 :(得分:1)
在Symfony profiler的帮助下,我调试了doctrine制作的查询,发现我需要使用simple_array
而不是array
作为@ORM\Column type
。
当我使用数组作为列类型时:doctrine会在将数据保存到数据库时序列化此数组,如a:0:{}
。这种方法的问题是当我尝试运行findby时:
..AND t0.selectedCountries IN ('de')..
..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']));
}