Symfony /主义findBy

问题描述 投票:0回答:2

希望创建通过json字段进行查询的自定义存储库功能。我的数据库中有params列,它们看起来像这样: "params": { "product": "stopper", "itemIdentifier": "" }

我想按产品价值查询记录。在这种情况下为止挡条件。

symfony doctrine
2个回答
0
投票

您可以通过一个经典示例来实现:

在您的存储库中:一个结果

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');

0
投票

如果我正确理解了您的问题,那么您的表中有一列名为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'的命名属性,这可能会造成混淆。目的是显示如何执行多级过滤。

© www.soinside.com 2019 - 2024. All rights reserved.