希望创建通过json字段进行查询的自定义存储库功能。我的数据库中有params列,它们看起来像这样:
"params": {
"product": "stopper",
"itemIdentifier": ""
}
我想按产品价值查询记录。在这种情况下为止挡条件。
您可以通过一个经典示例来实现:
在您的存储库中:一个结果
public function findOneProduct($value): ?Params
{
return $this->createQueryBuilder('p')
->andWhere('p.product = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
对于多个结果
public function findParamsByProduct($value): ?Params
{
return $this->createQueryBuilder('p')
->andWhere('p.product = :val')
->setParameter('val', $value)
->orderBy(/*some field */)
->setMaxResults(/*if needed*/)
->getQuery()
->getResults()
;
}
在您的控制器中:
$stoppers = $entityManager->getRepository(Params::class)->findParamsByProduct('stopper');
如果我正确理解了您的问题,那么您的表中有一列名为params。在此mysql列中,您存储JSON文本。
然后您要查询该表并通过查看列中的JSON进行过滤。
这可能有点乏味,并且过去也强烈建议这样做(在Mysql 5.7.8中的JSON类型之前)。最佳实践是将NoSQL数据库(例如MongoDB)存储为集合(表)中的实际JSON。
无论如何,有一个适合您的解决方案。
考虑到@AppyGG解释了如何进行自定义存储库功能。
首先,我们必须使用纯SQL进行查询。可以通过两种方式完成:
1。返回包含数据的数组。
$conn = $this->getEntityManager()->getConnection();
$sql = '
SELECT * FROM product p
WHERE p.price > :price
ORDER BY p.price ASC
';
$stmt = $conn->prepare($sql);
$stmt->execute(['price' => $price]);
// returns an array of arrays (i.e. a raw data set)
return $stmt->fetchAll();
2。返回水合实体
use Doctrine\ORM\Query\ResultSetMappingBuilder;
$rsm = new ResultSetMappingBuilder($entityManager);
$rsm->addRootEntityFromClassMetadata('MyProject\Product', 'p');
$sql = '
SELECT * FROM product p
WHERE p.price > :price
ORDER BY p.price ASC
';
$nql = $this->_em->createNativeQuery( $sql, $rsm );
$nql->setParameter('price', $price);
//Return loaded entities
return $nql->getResult();
现在,知道如何使用学说进行MySQL查询,我们希望选择以JSON数据过滤的结果。
我指的是这个漂亮的stackoverflow,它解释了这一切:How to search JSON data in MySQL?
那里提出的最简单的解决方案至少需要MySQL 5.7.8
您的MySQL查询如下:
//With $entity->getParams() == {"params": {"product":"stopper", "itemIdentifier":""}}
$conn = $this->getEntityManager()->getConnection();
$sql = '
SELECT * FROM Entity e
WHERE JSON_EXTRACT(e.params, "$.params.product") = :product
';
//Or Like this if the column is of Type JSON in MySQL(Not doctrine, yes check MySQL).
$sql = '
SELECT * FROM Entity e
WHERE e.params->"$.params.product" = :product
';
$stmt = $conn->prepare($sql);
$statement->bindValue("product","stopper");
$stmt->execute();
return $statement->fetchAll();
希望这会有所帮助!
P.S:请注意,我的示例使用了一个名为'params'的列,而Json也包含一个名为'params'的命名属性,这可能会造成混淆。目的是显示如何执行多级过滤。