Sol*_*BPS 8 php symfony doctrine-orm
我正在做一个小项目,其中有一个具有角色属性的实体,该属性由数组组成。
\n我想做的是,在某个控制器中,找到一个在角色数组中具有特定角色的现有实体。
\n我正在尝试使用findOneBy()方法,但我似乎无法使其工作,它总是返回 null,即使具有我试图找到的特定角色的实体存在。
这是我的实体及其属性:
\n/**\n * @ORM\\Entity(repositoryClass=SalarieRepository::class)\n */\nclass Salarie\n{\n /**\n * @ORM\\Id\n * @ORM\\GeneratedValue\n * @ORM\\Column(type="integer")\n */\n private $id;\n\n /**\n * @ORM\\Column(type="string", length=255)\n */\n private $nom;\n\n /**\n * @ORM\\Column(type="string", length=255)\n */\n private $prenom;\n\n /**\n * @ORM\\Column(type="string", length=255)\n */\n private $email;\n\n /**\n * @ORM\\Column(type="string", length=255, nullable=true)\n */\n private $telephone;\n\n /**\n * @ORM\\Column(type="string", length=255)\n */\n private $service;\n\n /**\n * @ORM\\Column(type="json")\n */\n private $roles = [];\n\n // Getters & setters\n}\nRun Code Online (Sandbox Code Playgroud)\nfindOneBy()这是我在控制器内部尝试的一个示例,它返回null,它返回:
$rolecheck = $this->salarieRepository->findOneBy(["roles" => ["ROLE_RESPONSABLE_RH"]]);\nRun Code Online (Sandbox Code Playgroud)\n当我尝试使用不是数组的实体的任何其他属性时,如果我执行以下操作,它会很好地工作:
\n$rolecheck = $this->salarieRepository->findOneBy(["nom" => "test"]);\ndd($rolecheck);\nRun Code Online (Sandbox Code Playgroud)\n它将显示正确的实体:
\nSalarieController.php on line 47:\nApp\\Entity\\Salarie {#1501 \xe2\x96\xbc\n -id: 6\n -nom: "test"\n -prenom: "test"\n -email: "test@test.test"\n -telephone: null\n -service: "Graphisme"\n -roles: array:3 [\xe2\x96\xbc\n 0 => "ROLE_RESPONSABLE_RH"\n 1 => "ROLE_RESPONSABLE_SERVICE"\n 2 => "ROLE_SALARIE"\n ]\n}\nRun Code Online (Sandbox Code Playgroud)\n我们还可以看到它确实有角色数组,其中包含我试图在其中找到的角色。
\n有关我如何尝试找到具有特定角色的实体的任何线索吗"ROLE_RESPONSABLE_RH"?
Aym*_*Dev 12
您的$roles属性的类型为json,这意味着它在数据库中存储如下:
["ROLE_RESPONSABLE_RH", "ROLE_RESPONSABLE_SERVICE", "ROLE_SALARIE"]
Run Code Online (Sandbox Code Playgroud)
您需要询问 Doctrine JSON 数组是否包含该角色,但您不能使用该findOneBy()方法来做到这一点。
当您遇到 ORM 限制时,您可以将本机查询与 ResultSetMapping 结合使用。它允许您使用 DBMS 的特定功能编写纯 SQL 查询,但仍然获取实体对象。
在您的类中创建此方法SalarieRepository:
public function findByRole(string $role): array
{
// The ResultSetMapping maps the SQL result to entities
$rsm = $this->createResultSetMappingBuilder('s');
$rawQuery = sprintf(
'SELECT %s
FROM salarie s
WHERE /* your WHERE clause depending on the DBMS */',
$rsm->generateSelectClause()
);
$query = $this->getEntityManager()->createNativeQuery($rawQuery, $rsm);
$query->setParameter('role', $role);
return $query->getResult();
}
Run Code Online (Sandbox Code Playgroud)
WHERE然后,您需要根据 DBMS 替换我在子句中放置的注释:
MariaDB - JSON_SEARCH():
SELECT %s
FROM salarie s
WHERE JSON_SEARCH(s.roles, 'one', :role) IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
MySQL - JSON_CONTAINS():
SELECT %s
FROM salarie s
WHERE JSON_CONTAINS(s.roles, :role, '$')
Run Code Online (Sandbox Code Playgroud)
警告:您必须role用双引号将参数引起来:
$query->setParameter('role', sprintf('"%s"', $role));
Run Code Online (Sandbox Code Playgroud)
PostgreSQL - jsonb 转义“?” 操作员:
SELECT %s
FROM salarie s
WHERE s.roles::jsonb ?? :role
Run Code Online (Sandbox Code Playgroud)
警告:需要 PHP 7.4+。请参阅RFC
| 归档时间: |
|
| 查看次数: |
8801 次 |
| 最近记录: |