gpt4 book ai didi

php - 原则 2 - 如何处理不同步的数据库/实体

转载 作者:行者123 更新时间:2023-12-04 06:38:24 29 4
gpt4 key购买 nike

我正在开发一个 PHP Web 应用程序,并希望将 Doctrine 2.0 用于 ORM 功能。但是,我在处理一种特定类型的查询时遇到了重大问题。

考虑一个包含 Foo 和 Bar 实体的简单域模型。一个 Foo 实体包含许多 Bars,一个 Bar 可能被标记为事件的。

/** @Entity */
class Foo
{
/** @OneToMany(targetEntity="Bar", mappedBy="foo") */
protected $bars;

/** Returns Bars marked as active. */
public function getActiveBars()
{
// XXX What goes here?
}
}

/** @Entity */
class Bar
{
/** @ManyToOne(targetEntity="Foo", inversedBy="bar") */
protected $foo;

/** @Column(type="boolean") */
protected $active;

/** ...setter omitted for clarity... */
}

我的问题是:什么代码应该放在getActiveBars中方法?

下面的代码工作正常,但当数据库中有许多非事件的 Bar 对象时,性能将成为一个问题。迭代 Bar 集合会导致对数据库执行大型查询。
function getActiveBars()
{
$ret = array();
foreach($this->bars as $bar) {
if ($bar->isActive()) $ret[] = $bar;
}
return $ret;
}

执行 DQL 查询,例如 SELECT b FROM Bar l WHERE b.active = true AND b.foo = :foo在 getActiveBar() 内似乎是解决方案,但是这样的查询不会检测到调用 EntityManager#flush() 之前对 Bar 所做的任何未完成的更改(因为 DQL 是针对数据库执行的)。

最佳答案

这可能不是世界末日。如果 Foo::bars 已加载、已被修改且尚未提交回数据库,则您唯一的选择是迭代。

如果 Foo::bars 没有被加载,那么它肯定没有被修改,所以你最好查询数据库。

(最后,如果 bar 已经被加载、修改并提交回来,bars 集合的大小将决定获取或迭代是否更好,可能)

这让我很好奇实体是否有办法判断集合成员是否已加载。

documentation似乎暗示代理 ArrayCollection(在您的示例中为 Foo:bars)不会传递 instanceof ArrayCollection测试。因此,您可能会尝试变得聪明,例如:

     class Foo {   
public function getActiveBars(){
if ($this->bars instanceof \Doctrine\Common\Collection\ArrayCollection){
//get active bars by iterating over $this->bars
}else{
//get active bars by DQL, and avoid loading $this->bars (for now).
}
}
}

关于php - 原则 2 - 如何处理不同步的数据库/实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4587857/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com