activerecord – 在Yii中批量插入

前端之家收集整理的这篇文章主要介绍了activerecord – 在Yii中批量插入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果插入所有对象,我需要在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();

当然,它可以更精细和扩展,以允许更新等

希望这可以帮助.

猜你在找的PHP相关文章