web-dev-qa-db-fra.com

Insertion par lots ActiveRecord (yii2)

Est-il possible d'insérer plusieurs lignes dans une requête avec ActiveRecord de Yii? Ou est-ce uniquement possible via les objets DAO de niveau inférieur?

34
user1561346

Vous pouvez utiliser la méthode batchInsert() de yii\db\Command. Voir les détails ici . Lorsque vous l'utilisez avec ActiveRecord assurez-vous de valider toutes les données avant de les insérer.

En supposant que vous avez un tableau de modèles $ avec la classe Post, cela peut être fait comme ceci:

$rows = [];
foreach ($models as $model) {
    if (!$model->validate()) {
        // At least one model has invalid data

        break;
    }

    $rows[] = $model->attributes;
}

Si les modèles ne nécessitent pas de validation, vous pouvez raccourcir le code ci-dessus en utilisant ArrayHelper pour construire $rows tableau.

use yii\helpers\ArrayHelper;

$rows = ArrayHelper::getColumn($models, 'attributes');

Ensuite, exécutez simplement l'insertion par lots:

$postModel = new Post;

Yii::$app->db->createCommand()->batchInsert(Post::tableName(), $postModel->attributes(), $rows)->execute();

P.S. Le $postModel juste utilisé pour extraire la liste des noms attirubute, vous pouvez également extraire cela de n'importe quel modèle $ existant dans votre tableau $ models.

Si vous n'avez pas besoin d'insérer tous les attributs, vous pouvez le spécifier lors du remplissage de $rows tableau:

$rows[] = [
    'title' => $model->title,
    'content' => $model->content,
];

N'oubliez pas de remplacer $postModel->attributes à ['title', 'content'].

En cas d'attributs plus importants, vous pouvez utiliser certaines fonctions de tableau pour spécifier les attributs exacts à insérer.

51
arogachev