如果插入所有对象,我需要在Yii中插入多个ActiveRecord对象
$transaction = Yii::app()->db->beginTransaction(); for ($i = 0;$i < 10;$i++){ $model = new Mymodel(); $model->x = $i; if (!$model->save()){ $transaction->rollback(); break; } } if ($transaction->active) $transaction->commit();
虽然不完全是Yii,但它可以作为扩展/组件,并且被视为普通命令,因此事务仍然适用.完全有可能将其设置为在查询中使用参数而不是字符串文字,并且还可以实现对null和默认值的检查.
class CDbMultiInsertCommand extends CDbCommand{ /** @var CActiveRecord $class */ private $class; /** @var string $insert_template */ private $insert_template = "insert into %s(%s) "; /** @var string $value_template */ private $value_template = "(%s)"; /** @var string $query */ public $query; /** @var CDbColumnSchema[] $columns */ private $columns; /** @var boolean $fresh */ private $fresh; /** @var CDbConnection $db */ private $db; /** @param CActiveRecord $class * @param CDbConnection $db */ public function __construct($class,$db = null){ $this->class = $class; $this->createTemplate(); if(is_null($db)){ $this->db = Yii::app()->db; } else{ $this->db = $db; } } private function createTemplate(){ $this->fresh = true; $value_template = ""; $columns_string = ""; $this->columns = $this->class->getMetaData()->tableSchema->columns; $counter = 0; foreach($this->columns as $column){ /** @var CDbColumnSchema $column */ if($column->autoIncrement){ $value_template .= "0"; } else if($column->type == "integer" || $column->type == "boolean" || $column->type == "float" || $column->type == "double") { $value_template .= "%d"; } else{ $value_template .= "\"%s\""; } $columns_string .= $column->name; $counter ++; if($counter != sizeof($this->columns)){ $columns_string .= ","; $value_template .= ","; } } $this->insert_template = sprintf($this->insert_template,$this->class->tableName(),$columns_string); $this->value_template = sprintf($this->value_template,$value_template); } /** @param boolean $validate * @param CActiveRecord $record */ public function add($record,$validate = true){ $values = array(); if($validate){ if(!$record->validate()){ return false; } } $counter = 0; foreach($this->columns as $column){ if($column->autoIncrement){ continue; } $values[$counter] = $this->class->{$column->name}; $counter ++; } if(!$this->fresh){ $this->query .= ","; } else{ $this->query = "values"; } $this->fresh = false; $this->query .= vsprintf($this->value_template,$values); return true; } public function getConnection(){ return $this->db; } public function execute(){ $this->setText($this->insert_template." ".$this->query); return parent::execute(); } }
用法是:
$transaction = Yii::app()->db->beginTransaction(); $multi = new CDbMultiInsertCommand(new Mymodel()); for ($i = 0;$i < 10;$i++){ $model = new Mymodel(); $model->x = $i; $multi->add($model,$shouldBeValidated); } $multi->execute(); if ($transaction->active) $transaction->commit();
当然,它可以更精细和扩展,以允许更新等
希望这可以帮助.