如果插入所有对象,我需要在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();
当然,它可以更精细和扩展,以允许更新等
希望这可以帮助.