Doctrine2 - 一次查询中多条记录的插入

3
我原以为Doctrine2会优化我的查询,以便为任何数据库事务提供最佳性能。
我要在数据库表中插入大约500条记录,然后我注意到它创建了500多个查询来插入这些记录(每条记录一个查询),我想知道为什么Doctrine不使用多个插入一次性插入所有记录,这样不是可以减少负载并优化查询吗?我对Doctrine的这种行为有所疑问,是否有什么我没有理解到的东西?
这是我用于插入的代码:
$content = json_decode($response->getBody());
$em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
foreach ($content as $value) {
    $log = new log();
    $log->fromArray($value);
    $em->persist($log);
}
$em->flush();

更新1:
以下是所请求的fromArray()函数的内容,该函数的目的是从数组中将值合并到类属性中:

/**
 * Map parameters with class property.
 *
 * @param $array array
 * @access public
 * @return $this
 */
public function fromArray(array $array)
{
    foreach ($array as $property => $value) {
        $method = 'set'.ucwords($property);
        $this->$method($value);
    }
    return $this;
}

以下为$content的内容:

Array
(
    [0] => stdClass Object
    (
        [id] => 111
        [guid] => aaaa-bbbb-cccc
        [wid] => 100
        [pid] => 101
        [start] => 2014-11-22T12:44:44+00:00
        [stop] => 2014-11-22T15:23:11+00:00
        [duration] => 9507
        [description] => Log description
        [tags] => Array
            (
                [0] => test
            )
        [at] => 2014-11-24T07:28:09+00:00
        [uid] => 51
    )
    [1] => stdClass Object
    (
        [id] => 112
        [guid] => dddd-eee
        [wid] => 100
        [pid] => 101
        [billable] => 
        [start] => 2014-11-22T15:35:07+00:00
        [stop] => 2014-11-22T15:45:21+00:00
        [duration] => 614
        [description] => Lorem description
        [tags] => Array
            (
                [0] => php
                [1] => pm
            )
        [at] => 2014-11-24T04:35:30+00:00
        [uid] => 51
    )
)

Doctrine不会以神奇的方式处理您的请求,它只会按照您的要求执行。您在foreach中持续进行(正如我所看到的那样),可能有超过500条记录...在发送数据到persist方法之前,您必须解决这个问题,我的意思是您必须使用更好的去规范化的方式。 - ilhnctn
@İlhanÇetinm 谢谢您的回复,我理解这里没有什么魔法,这不是查询优化的基础吗?既然这是插入的默认方法,那么我想知道Doctrine是否允许批量插入? - Ibrahim Azhar Armar
@İlhanÇetin 我不确定我是否正确地理解了您的意思,如果您能举个例子,我会很感激。 - Ibrahim Azhar Armar
请问您能否分享fromArray()的内容以及在pastebin或gist上提供一个$value实例? - ilhnctn
@İlhanÇetin 更新了代码,请告诉我这个是否有效。 - Ibrahim Azhar Armar
我将与我的同事一起控制并返回。在我看来仍然没有任何异常。 - ilhnctn
1个回答

2
请查看这个文档。在每次迭代中,Doctrine会为您创建一个insert ...查询,最后,当您调用flush()时,Doctrine会在循环内一次性将所有这些插入查询发送到数据库(使用类似foreach(queries as query) { run->query.. }的机制)。
在您的情况下,任何这些查询都是插入查询,因此,正如我在评论中所述,在您的情况下没有异常情况。ORM可能并不适用于所有情况。

1
问题是,为什么Doctrine在每次迭代中都创建一个插入查询,而不是利用多个插入? - Ibrahim Azhar Armar
请查看我提供的文档。答案在一个警告类别下给出以引起注意。 - ilhnctn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接