activerecord – 在Yii中批量插入

前端之家收集整理的这篇文章主要介绍了activerecord – 在Yii中批量插入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果插入所有对象,我需要在Yii中插入多个ActiveRecord对象
  1. $transaction = Yii::app()->db->beginTransaction();
  2. for ($i = 0;$i < 10;$i++){
  3. $model = new Mymodel();
  4. $model->x = $i;
  5. if (!$model->save()){
  6. $transaction->rollback();
  7. break;
  8. }
  9. }
  10. if ($transaction->active)
  11. $transaction->commit();

现在我需要在一个查询中插入所有这些内容,如何在使用活动记录时执行此操作?

虽然不完全是Yii,但它可以作为扩展/组件,并且被视为普通命令,因此事务仍然适用.完全有可能将其设置为在查询中使用参数而不是字符串文字,并且还可以实现对null和默认值的检查.
  1. class CDbMultiInsertCommand extends CDbCommand{
  2.  
  3. /** @var CActiveRecord $class */
  4. private $class;
  5.  
  6. /** @var string $insert_template */
  7. private $insert_template = "insert into %s(%s) ";
  8.  
  9. /** @var string $value_template */
  10. private $value_template = "(%s)";
  11.  
  12. /** @var string $query */
  13. public $query;
  14.  
  15. /** @var CDbColumnSchema[] $columns */
  16. private $columns;
  17.  
  18. /** @var boolean $fresh */
  19. private $fresh;
  20.  
  21. /** @var CDbConnection $db */
  22. private $db;
  23.  
  24. /** @param CActiveRecord $class
  25. * @param CDbConnection $db
  26. */
  27. public function __construct($class,$db = null){
  28. $this->class = $class;
  29. $this->createTemplate();
  30. if(is_null($db)){
  31. $this->db = Yii::app()->db;
  32. }
  33. else{
  34. $this->db = $db;
  35. }
  36. }
  37. private function createTemplate(){
  38. $this->fresh = true;
  39. $value_template = "";
  40. $columns_string = "";
  41. $this->columns = $this->class->getMetaData()->tableSchema->columns;
  42. $counter = 0;
  43. foreach($this->columns as $column){
  44. /** @var CDbColumnSchema $column */
  45. if($column->autoIncrement){
  46. $value_template .= "0";
  47. }
  48. else if($column->type == "integer" || $column->type == "boolean" || $column->type == "float" || $column->type == "double") {
  49. $value_template .= "%d";
  50. }
  51. else{
  52. $value_template .= "\"%s\"";
  53. }
  54. $columns_string .= $column->name;
  55. $counter ++;
  56. if($counter != sizeof($this->columns)){
  57. $columns_string .= ",";
  58. $value_template .= ",";
  59. }
  60. }
  61.  
  62. $this->insert_template = sprintf($this->insert_template,$this->class->tableName(),$columns_string);
  63. $this->value_template = sprintf($this->value_template,$value_template);
  64. }
  65.  
  66. /** @param boolean $validate
  67. * @param CActiveRecord $record
  68. */
  69. public function add($record,$validate = true){
  70. $values = array();
  71. if($validate){
  72. if(!$record->validate()){
  73. return false;
  74. }
  75. }
  76. $counter = 0;
  77. foreach($this->columns as $column){
  78. if($column->autoIncrement){
  79. continue;
  80. }
  81. $values[$counter] = $this->class->{$column->name};
  82. $counter ++;
  83. }
  84. if(!$this->fresh){
  85. $this->query .= ",";
  86. }
  87. else{
  88. $this->query = "values";
  89. }
  90. $this->fresh = false;
  91. $this->query .= vsprintf($this->value_template,$values);
  92. return true;
  93. }
  94.  
  95. public function getConnection(){
  96. return $this->db;
  97. }
  98.  
  99. public function execute(){
  100. $this->setText($this->insert_template." ".$this->query);
  101. return parent::execute();
  102. }
  103. }

用法是:

  1. $transaction = Yii::app()->db->beginTransaction();
  2. $multi = new CDbMultiInsertCommand(new Mymodel());
  3. for ($i = 0;$i < 10;$i++){
  4. $model = new Mymodel();
  5. $model->x = $i;
  6. $multi->add($model,$shouldBeValidated);
  7. }
  8.  
  9. $multi->execute();
  10.  
  11. if ($transaction->active)
  12. $transaction->commit();

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

希望这可以帮助.

猜你在找的PHP相关文章