Doctrine 多对多批量插入

Doctrine Many-To-Many bulk insert

我需要批量插入数千条记录(5k 到 20k)。 场景是User<->n:m<->Group。用户列表是通过具有许多连接的复杂查询获得的。 我可以访问生成列表的 QueryBuilder。 将用户添加到组的最简单方法是

$users = $this->repository->findRecipientsByCriteria($group->getCriteria());
foreach ($users as $user){
    $group->addUser($user);
}

但就所涉及的用户数量而言,我认为这不是一个好主意(就性能而言)。 由于获取连接关系,我什至无法迭代结果。

我想将 QueryBuilder Dql(或 Sql)注入 INSERT 语句? 我的意思是:

$qb = $this->repository->getRecipientsByCriteriaQueryBuilder($group->getCriteria());
$qb->select("'".$group->getId()."' AS gruppo_id, U.id AS utente_id");
$d = $qb->getQuery()->getSQL();
$q = $this->entityManager->createNativeQuery('INSERT INTO `msg_gruppo_utente` (`gruppo_id`, `utente_id`) '.$d, new ResultSetMapping());
$q->execute();

但这会导致

INSERT INTO `msg_gruppo_utente` (`gruppo_id`, `utente_id`) SELECT '64f105a3-a6ab-460a-8378-84b0c3258601' AS sclr_0, s0_.id AS id_1 FROM security_utente s0_ INNER JOIN security_utente_cliente s1_ ON s0_.id = s1_.utente_id INNER JOIN api_cliente a2_ ON s1_.cliente_id = a2_.id INNER JOIN api_indirizzo_cliente a3_ ON a2_.id = a3_.cliente_id INNER JOIN api_contratto a4_ ON a2_.id = a4_.cliente_id WHERE s1_.verificato = ? AND a3_.city = ?

哪里没有设置参数,而我认为应该在getRecipientsByCriteriaQueryBuilder中设置参数

由于doctrine native SQL resctrictions

If you want to execute DELETE, UPDATE or INSERT statements the Native SQL API cannot be used and will probably throw errors. Use EntityManager#getConnection() to access the native database connection and call the executeUpdate() method for these queries.

我用过这个解决方案(executeUpdate 被弃用,取而代之的是 executeStatement

$usersQueryBuilder = $this->repository->getRecipientsByCriteriaQueryBuilder($group->getCriteria());
$usersQueryBuilder->select("'".$group->getId()."' AS gruppo_id, U.id AS utente_id");
$parameters = $usersQueryBuilder->getParameters();
$p = [];
/** @var Parameter $parameter */
foreach ($parameters as $parameter){
    $p[] = $parameter->getValue();
}
$conn = $this->entityManager->getConnection();
$conn->executeStatement('INSERT INTO `msg_gruppo_utente` (`gruppo_id`, `utente_id`) '.
    $usersQueryBuilder->getQuery()->getSQL(), $p);