Symfony学说查询构建器喜欢在PostgreSQL中工作



,所以我有一个包含以下代码

的用户repository
namespace AppBundleRepository;
use DoctrineORMEntityRepository;
class UserRepository extends EntityRepository
{
    public function findByRole($role)
    {
        $qb = $this->_em->createQueryBuilder();
        $qb->select('u')
            ->from($this->_entityName, 'u')
            ->where('u.roles LIKE :roles')
            ->setParameter('roles', '%"'.$role.'"%');
        return $qb->getQuery()->getResult();
    }
}

如果我的数据库是mySQL,这似乎很好地工作正常,但是如果我将数据库更改为PostgreSql,则此查询会引发以下错误

执行'选择p0_.id作为id_0, p0_.username as username_1,p0_.password as password_2,p0_.is_active 作为is_Active_3,p0_.Roles as roles_4,p0_.name as name_5,p0_.street 作为street_6,p0_.city为city_7,p0_.state as State_8,p0_.zip_code as zip_code_9,p0_.phone_number as phone_number_10,p0_.dob as dob_11, p0_.company_name as Company_name_12,p0_.company_slug as company_slug_13,p0_.company_logo as Company_logo_14, p0_.company_details as Company_details_15,p0_.stripe_customer_id as stripe_customer_id_16,p0_.created_at as create_at_17,p0_.updated_at 作为px_user p0_的Updated_at_18,p0_.Roles喜欢?'使用参数 ["%" cole_employer "%"]:

sqlstate [42883]:未定义的功能:7错误:不存在操作员: json ~~未知行1:... AS AS AS UPDATED_AT_18来自PX_USER P0_ P0_.Roles,例如$ 1 ^提示:没有操作员匹配给定名称,并且 参数类型。您可能需要添加明确的类型铸件。

这是我第一次使用PostgreSQL,因此我没有得到问题。如果我通过添加以下一件

将生成的查询更改为一段时间后
WHERE 
  p0_.roles::text LIKE '%ROLE_EMPLOYER%'

一切正常。注意 :: text

所以现在如何将其添加到查询构建器中,因此它也可以与PostgreSQL一起使用。

我解决了模块boldtrn/jsonb-bundle的问题,但根据所使用的Postgres版本,它创建了一个错误。

我还通过这样的本机查询解决了没有模块的问题:

public function findEmailsByRole($role)
{
    return $this->_em->getConnection()->executeQuery(
        "SELECT email FROM public.utilisateur WHERE roles::text LIKE :role",
        ['role'=>'%"' . $role . '"%']
    )->fetchAll();
}

您可以创建自己的功能

ps:我也在postgresql上工作

    public function findByRole($role) {
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb->select('u')
            ->from($this->getEntityName(), 'u')
            ->where("u.roles LIKE '%$role%'")
    ;
    return $qb->getQuery()->getResult();
}

我通过使用JSONBBUNDLE解决了问题。

我采取的以下步骤修复了

$ composer require "boldtrn/jsonb-bundle

通过在其各自的位置添加以下内容来更新config.yml

doctrine:
    dbal:
        types:
          jsonb: BoldtrnJsonbBundleTypesJsonbArrayType
        mapping_types:
          jsonb: jsonb
    orm:
        dql:
            string_functions:
                JSONB_AG:   BoldtrnJsonbBundleQueryJsonbAtGreater
                JSONB_HGG:  BoldtrnJsonbBundleQueryJsonbHashGreaterGreater
                JSONB_EX:   BoldtrnJsonbBundleQueryJsonbExistence

roles属性更改为类型jsonb

和存储库中的以下查询工作

$query = $this->getEntityManager()->createQuery("SELECT u FROM AppBundle:User u WHERE JSONB_HGG(u.roles , '{}') LIKE '%EMPLOYER%' ");
$users = $query->getResult();
return $users;

信用转到学说查询postgres json(包含)json_array

public function findByRole($role)
{
    $qb = $this->getEntityManager()->createQueryBuilder();
    $qb->select('u')
        ->from($this->getEntityName(), 'u')
        ->where($qb->expr()->like('u.roles', ':roles')
        ->setParameter('roles', $qb->expr()->literal('%'.$role.'%'));
    return $qb->getQuery()->getResult();
}

将您的自定义字符串DQL替换为QueryBuilder语法。

我不知道它是否可能与您的类似语句中的语法有关: '%".$var."%',这可能会陷入困境。希望这可以帮助您解决它。

学说QueryBuilder文档如下:

// Example - $qb->expr()->like('u.firstname', $qb->expr()->literal('Gui%'))
public function like($x, $y); // Returns ExprComparison instance

从postgresql文档中看起来像是这样,您可能需要执行此操作:

$qb = $this->_em->createQueryBuilder();
$qb->select('u')
    ->from($this->_entityName, 'u')
    ->where('u.roles LIKE :roles')
    ->setParameter('roles', ''%'.$role.'%'');
return $qb->getQuery()->getResult();

基本上通过逃脱百分比符号以外的单引号。我不确定这是否会起作用,但是您可以尝试吗?

在@lou zito上构建答案:

如果您正在与Postgres打交道,请学习JSON/B操作的力量!

将JSON/B阵列施放到文本中以进行比较不是一个好方法。改为将其投入JSONB(甚至更好:更改您的设置/迁移(S)直接使用JSONB字段< 3)

您可以使用?操作员,或包含操作员@>作为示例。

请参阅可用的JSONB操作员的完整列表请注意,?将被解释为学说占位持有人,您需要使用??逃脱它!

public function findByRole()
{
    return $query = $this->getEntityManager()
        ->getConnection()
        ->executeQuery(<<<'SQL'
            SELECT id FROM public.user
            WHERE roles::jsonb ?? :role
            ORDER BY last_name, first_name
SQL,
            ['role' => User::ROLE_XYZ]
        )->fetchAllAssociative();
}

提示:如上所述,您通常会在用户实体中将角色作为公共字符串常数提取,以方便访问。我强烈建议也是最佳实践。

相关内容

  • 没有找到相关文章

最新更新