Symfony上的实体经理的表现

时间:2017-04-29 07:54:47

标签: php symfony doctrine

我必须为数据迁移制作一个命令但是执行时间过长而且很长一段时间后崩溃,我需要加快速度,你能帮助我吗?这是一个例子:

  1. 情况

    • 我有一个物质实体
    • 我有一个客户实体
    • 我有一个MatterCustomer实体
    • 物质有一个或多个物质顾客
    • 客户可以在无或多物质客户中 请注意,实体之间的链接已正确设置为
  2. 命令

    function execute(InputInterface $input, OutputInterface $output)
    {
        // Here connection to old database
        $this->pdo = $this->container()->get('app.command_oldbase.odbase_helper')->connectToDatabase();
        $em = $this->getContainer()->get('doctrine')->getManager();
        $em->getConnection()->beginTransaction()
        $em->getConnection()->setAutoCommit(false);
        try{
            $this->migrateMatters($output);
        } catch (Exception $e) {
            $em->getConnection()->rollback();
            throw $e;
        }
        $em->getConnection()->commit();
    }
    
    function migrateMatters(OutputInterface $output)
    {
        $statement = $this->pdo->prepare('Select id,name From oldmatter');
        $statement->execute();
        $oldmatters = $statement->fetchAll();
    
        foreach ($oldmatters As $oldmatter) {
           $this->em = $this->getContainer()->get('doctrine')->getManager();
           $matter = (new Matter())
               ->setName($oldmatter['name'])
           ;
           $this->em->persist($matter);
           $this->em->flush();
    
           $this->setMatterCustomer($matter, $oldmatter['id']);
    
           $this->em->clear();
        }
    }
    
    function setMatterCustomer(Matter $matter, int $oldmatter_id)
    {
        $statement = $this->pdo->prepare('Select customername From oldmattercustomers Where oldmatter_id = :oldmatter_id');
        $statement->bindParam(':oldmatter_id', $oldmatter_id);
        $statement->execute();
        $oldcustomers = $statement->fetchAll();
    
        foreach ($oldcustomers As $oldcustomer) {
            //search customer in Customer entity 
            $customer = $this->em->getRepository(Customer::class)->findOneBy(['name' => $oldcustomer['customername']]);
    
            //search if MatterCustomer exist
            $matterCustomer = $this->em->getRepository(MatterCustomer::class)->findOneBy(['matter' => $matter, 'customer' => $customer]);
    
            if ($matterCustomer == null) {
                $matterCustomer = (new MatterCustomer())
                   ->setContact($contact)
                   ->setMatter($matter)
                ;
                //add MatterCustomer to arrayCollection in Matter
                $matter->addCustomer($matterCustomer);
                $this->em->persist($matter);
                $this->em->flush();
            }
        }
     }
    

1 个答案:

答案 0 :(得分:1)

  1. 使用batch processing

  2. 对物质客户使用cascade persist。因此,首先需要创建Matter实例,然后添加到实例MatterCustomer等等。然后当然只执行持久化Matter实例。

  3. 如果有多个实体,可能禁用日志记录会减少内存消耗

  4. $this->em->getConnection()->getConfiguration()->setSQLLogger(null);

    1. 使用--no-debug选项运行命令(或在prod模式下),它将减少内存消耗。