You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Doctrine技术问询:如何用PHP结合Doctrine编写指定JSON查询(含可选参数)

使用PHP结合Doctrine实现指定JSON条件查询

需求说明

要实现对应SQL的查询逻辑,其中7作为可选参数:desired,仅当参数存在时才添加JSON包含检查条件。


方式一:使用Doctrine QueryBuilder(ORM风格)

适合用实体类映射数据库表的场景,通过QueryBuilder构建安全的DQL查询:

use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Club; // 假设你的实体类是Club,对应club表

class ClubRepository
{
    public function __construct(private EntityManagerInterface $entityManager) {}

    public function getClubs(int $clubId, ?string $desiredActivity = null)
    {
        // 初始化QueryBuilder
        $qb = $this->entityManager->createQueryBuilder();
        $qb->select('c')
           ->from(Club::class, 'c')
           ->where('c.club = :clubId')
           ->setParameter('clubId', $clubId);

        // 处理可选参数:仅当desiredActivity不为空时添加JSON条件
        if ($desiredActivity !== null) {
            // 调用MySQL原生JSON函数,通过Doctrine表达式构建条件
            $jsonCondition = $qb->expr()->isTrue(
                $qb->expr()->func(
                    'JSON_CONTAINS',
                    $qb->expr()->func('JSON_EXTRACT', 'c.data', '$.activities.*'),
                    ':desired',
                    '$'
                )
            );
            $qb->andWhere($jsonCondition)
               // 注意:如果数据库中activities是字符串数组,参数需要带双引号;数字数组则直接传数值
               ->setParameter('desired', sprintf('"%s"', $desiredActivity));
        }

        // 执行查询并返回结果
        return $qb->getQuery()->getResult();
    }
}

调用示例

// 获取EntityManager实例(根据你的框架,比如Symfony可通过依赖注入获取)
$clubRepo = $entityManager->getRepository(Club::class);

// 1. 仅查询club=34558的记录
$clubs = $clubRepo->getClubs(34558);

// 2. 同时检查activities包含"7"的记录
$clubsWithActivity7 = $clubRepo->getClubs(34558, '7');

方式二:使用原生SQL查询

如果不需要实体映射,直接执行原生SQL更直观:

use Doctrine\ORM\EntityManagerInterface;

class ClubService
{
    public function __construct(private EntityManagerInterface $entityManager) {}

    public function getClubs(int $clubId, ?string $desiredActivity = null)
    {
        $sql = 'SELECT * FROM club WHERE club = :clubId';
        $params = ['clubId' => $clubId];

        // 添加可选的JSON条件
        if ($desiredActivity !== null) {
            $sql .= ' AND JSON_CONTAINS(JSON_EXTRACT(data, \'$.activities.*\'), :desired, \'$\') IS true';
            $params['desired'] = sprintf('"%s"', $desiredActivity);
        }

        // 执行原生SQL
        $stmt = $this->entityManager->getConnection()->prepare($sql);
        $stmt->execute($params);

        // 返回关联数组格式的结果
        return $stmt->fetchAllAssociative();
    }
}

注意事项

  • 始终使用参数绑定(:clubId、:desired)避免SQL注入风险,不要直接拼接参数到SQL字符串中。
  • 根据数据库中data->activities的实际类型调整参数格式:如果是数字数组,参数直接传数值(如7)即可;如果是字符串数组,需要包裹双引号(如"7")。

内容的提问来源于stack exchange,提问作者vukojevicf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:41:30