数组字段包含元素的原则

Doctrine where array field contains element

我有一个实体有 array 属性:

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

如何进行查询以提取包含特定元素的所有实体?像这样:

$entities = $this->createQueryBuilder('e')
    ->where($qb->expr()->contains('e.provinces', ':element'))
    ->setParameter('element', $element)
    ->getQuery()
    ->getResult()
;

首先你要明白Doctrine array type代表什么,所以基本上Doctrine数组类型转化为SQL text type 这只是一个序列化的字符串。因此,您可以使用学说表达式 like 创建一个查询,这样您的查询看起来就像这样

$entities = $this->createQueryBuilder('e')
    ->where($qb->expr()->like('e.provinces', ':element'))
    ->setParameter('element', '%' . \serialize($element) . '%')
    ->getQuery()
    ->getResult()
;

相当于 SQL 'SELECT ... WHERE e.provinces LIKE "%' . \serialize($element) . '%";'


但是因为你在你的问题中包含了 [sql] 标签我想告诉你这不是处理这种情况的正确方法,你的数据库违反了 1NF .在 Web 开发中,违反规范化形式是很常见的事情,您可以在内容管理系统存储配置时看到它,但它们不会尝试查询这些配置参数。在你的例子中,你希望查询省份,所以通常你应该努力查询索引字段,以提高查询的性能。

因此,解决方案可能是创建一个 省实体 并将 array 类型替换为 ManyToMany 关系。