【问题标题】:Doctrine where array field contains element数组字段包含元素的原则
【发布时间】:2018-03-02 13:18:03
【问题描述】:

我有一个具有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()
;

【问题讨论】:

标签: sql arrays doctrine query-builder


【解决方案1】:

首先你要明白Doctrine array type代表什么,所以基本上Doctrine数组类型翻译成SQL文本类型,它只是一个序列化的字符串。因此,您可以使用教义表达式 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 关系。

【讨论】:

  • 谢谢!由于省代码是 2 个字符的字符串,我可以安全地使用您的 LIKE 示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多