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

标签 php orm doctrine-orm

我正在开发一个 PHP Web 应用程序,并希望使用 Doctrine 2.0 来实现 ORM 功能。但是,我在处理一种特定类型的查询时遇到了很大的麻烦。

考虑一个包含 Foo 和 Bar 实体的简单域模型。一个 Foo 实体包含许多 Bar,并且一个 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/

相关文章:

java - JPA : Which should I use? 基本(可选)或列(可为空)?

php - Kohana 2 ORM 自定义主键生成错误

Django 跨反向关系聚合

php - 电影数据库的sql symfony实体关系orm

symfony - Symfony2 中的服务依赖注入(inject)

php - 我无法显示表格中的所有内容,它只显示最后一条记录

php - 在 laravel 5.2 中使用默认身份验证路由对用户进行身份验证后设置 session 数据

doctrine-orm - TYPO3:如何为 Doctrine insert() 迁移 $GLOBALS ['TYPO3_DB' ]->quoteStr()

php - 当字符串包含数字时 Preg_replace 不起作用

php - 带有 HTML 标签的 TWIG 变量