使用Doctrine2,我试图在一个实体上执行findOneBy
,在那里我使用OneToOne
连接了一个表,我想在连接表中搜索列。
这两个PHP实体是(简化版):
:
use DoctrineORMMapping as ORM;
/**
* @ORMEntity
* @ORMTable(name="Page")
* @ORMHasLifecycleCallbacks()
*/
class Page extends EntityInterface
{
/**
* @ORMId
* @ORMColumn(type="integer")
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORMColumn(type="boolean")
*/
public $isActive;
/**
* @ORMOneToOne(targetEntity="PageLocalization")
* @ORMJoinColumns({
* @ORMJoinColumn(name="id", referencedColumnName="pageId")
* })
**/
public $pageLocalization;
}
PageLocalization :
use DoctrineORMMapping as ORM;
/**
* @ORMEntity
* @ORMTable(name="PageLocalization")
* @ORMHasLifecycleCallbacks()
*/
class PageLocalization extends EntityInterface
{
/**
* @ORMId
* @ORMColumn(type="integer")
*/
public $pageId;
/**
* @ORMColumn(type="string")
*/
public $localeCode;
/**
* @ORMColumn(type="string")
*/
public $title;
}
实体工作,我可以通过例如$entityRepository->findOneBy(["id"=>1])
提取数据。
现在,例如,我想搜索Page.id = 1
, Page.isActive = true
和PageLocalization.localeCode = "en-US"
。这个搜索是如何执行的?
我下面的尝试没有成功。
$entityRepository->findOneBy([
"id" => 1,
"isActive" => true,
"pageLocalization" => [
"localeCode" => "en-US"
]
]);
我没有幸运地通过Google, Stackoverflow或Doctrine2文档找到答案。
我看到的最常见的解决方案是人们满足于使用$entityManager->createQueryBuilder()
手动构建查询。但是,我觉得这种方法违背了使用实体的目的。
这种类型的搜索是否可能使用纯注释和实体?
从我收集到目前为止,它确实是不可能执行这样的搜索跨多个实体(连接表)使用任何EntityRepository
的"查找"方法;find
, findAll
, findBy
, findOneBy
.
Stackoverflow回答类似的问题:
- https://stackoverflow.com/a/16730168/1879194
- https://stackoverflow.com/a/12258270/1879194
- https://stackoverflow.com/a/19489147/1879194
这样的例子不胜枚举。
结论必须使用DQL或QueryBuilder
来执行这种类型的搜索。
我发现这个限制非常令人讨厌,是Doctrine2中一个严重的功能缺陷。
如果有一半的时间,当我想要访问数据库时,我必须自己构建查询,为什么我要坚持和维护两种截然不同的方法;(1)一个ORM与实体反映数据库表和(2)构造纯SQL请求通过一个DBAL,例如PDO或Doctrine的DQL?
Doctrine2注意事项(稍微偏离主题)
我真的很想学习如何有效地使用Doctrine2。虽然Doctrine2确实有很多漂亮的功能,但它当然也包括一些巨大的钢筋墙,人们经常会撞到它的脸。Google和Stackoverflow当然有一堆"为什么我不能…?"的问题,特别是与Doctrine2和连接表有关。