,所以我有一个包含以下代码
的用户repositorynamespace 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();
}
提示:如上所述,您通常会在用户实体中将角色作为公共字符串常数提取,以方便访问。我强烈建议也是最佳实践。