Activerecord Yii:在一个查询中保存多条记录
我试图在循环中保存许多CActiveRecord模型对象。 我有这样的想法:Activerecord Yii:在一个查询中保存多条记录,activerecord,yii,model,Activerecord,Yii,Model,我试图在循环中保存许多CActiveRecord模型对象。 我有这样的想法: foreach ($array_of_items as $item) { $values = array( "title" => $item->title, "content" => $item->content, ); $object = new MyModel; $object->attributes = $val
foreach ($array_of_items as $item) {
$values = array(
"title" => $item->title,
"content" => $item->content,
);
$object = new MyModel;
$object->attributes = $values;
$object->save();
}
在我的例子中,这将创建大约400个CActiveRecord对象。保存过程非常慢,因为每次保存都会查询数据库
有没有办法一次性保存所有这些对象?
比如:
$objects = array();
foreach ($array_of_items as $item) {
$values = array(
"title" => $item->title,
"content" => $item->content,
);
$object = new MyModel;
$object->attributes = $values;
$objects[] = $object;
}
save_all_objects($objects);
我找不到关于这个问题的任何东西。有人吗?您可以验证您的模型,如果没有问题,您可以将其追加为sql文本以供插入
循环之后,只需使用数据库commandBuilder并执行准备好的文本
$sql = '';
if($object->validate())
{
$sql .= ',("' . $object->attr1 . '")'// append to script,(you get the idea, you need to also make a correct values)
}
...
if(!empty($sql))
{
$sql = 'INSERT INTO table (attr1) Values' . $sql;// make complete script
// execute that command
}
您可以验证您的模型,如果没有问题,您可以附加它,以便插入sql文本
循环之后,只需使用数据库commandBuilder并执行准备好的文本
$sql = '';
if($object->validate())
{
$sql .= ',("' . $object->attr1 . '")'// append to script,(you get the idea, you need to also make a correct values)
}
...
if(!empty($sql))
{
$sql = 'INSERT INTO table (attr1) Values' . $sql;// make complete script
// execute that command
}
对于“插入多行”,请将此代码放在GeneralRepository.php文件名下的components文件夹中
<?php
class GeneralRepository
{
/**
* Creates and executes an INSERT SQL statement for several rows.
* By: Nabi K.A.Z. <www.nabi.ir>
* Version: 0.1.0
* License: BSD3
*
* Usage:
* $rows = array(
* array('id' => 1, 'name' => 'John'),
* array('id' => 2, 'name' => 'Mark')
* );
* GeneralRepository::insertSeveral(User::model()->tableName(), $rows);
*
* @param string $table the table that new rows will be inserted into.
* @param array $array_columns the array of column datas array(array(name=>value,...),...) to be inserted into the table.
* @return integer number of rows affected by the execution.
*/
public static function insertSeveral($table, $array_columns)
{
$connection = Yii::app()->db;
$sql = '';
$params = array();
$i = 0;
foreach ($array_columns as $columns) {
$names = array();
$placeholders = array();
foreach ($columns as $name => $value) {
if (!$i) {
$names[] = $connection->quoteColumnName($name);
}
if ($value instanceof CDbExpression) {
$placeholders[] = $value->expression;
foreach ($value->params as $n => $v)
$params[$n] = $v;
} else {
$placeholders[] = ':' . $name . $i;
$params[':' . $name . $i] = $value;
}
}
if (!$i) {
$sql = 'INSERT INTO ' . $connection->quoteTableName($table)
. ' (' . implode(', ', $names) . ') VALUES ('
. implode(', ', $placeholders) . ')';
} else {
$sql .= ',(' . implode(', ', $placeholders) . ')';
}
$i++;
}
$command = Yii::app()->db->createCommand($sql);
return $command->execute($params);
}
}
对于“插入多行”,请将此代码放在GeneralRepository.php文件名下的components文件夹中
<?php
class GeneralRepository
{
/**
* Creates and executes an INSERT SQL statement for several rows.
* By: Nabi K.A.Z. <www.nabi.ir>
* Version: 0.1.0
* License: BSD3
*
* Usage:
* $rows = array(
* array('id' => 1, 'name' => 'John'),
* array('id' => 2, 'name' => 'Mark')
* );
* GeneralRepository::insertSeveral(User::model()->tableName(), $rows);
*
* @param string $table the table that new rows will be inserted into.
* @param array $array_columns the array of column datas array(array(name=>value,...),...) to be inserted into the table.
* @return integer number of rows affected by the execution.
*/
public static function insertSeveral($table, $array_columns)
{
$connection = Yii::app()->db;
$sql = '';
$params = array();
$i = 0;
foreach ($array_columns as $columns) {
$names = array();
$placeholders = array();
foreach ($columns as $name => $value) {
if (!$i) {
$names[] = $connection->quoteColumnName($name);
}
if ($value instanceof CDbExpression) {
$placeholders[] = $value->expression;
foreach ($value->params as $n => $v)
$params[$n] = $v;
} else {
$placeholders[] = ':' . $name . $i;
$params[':' . $name . $i] = $value;
}
}
if (!$i) {
$sql = 'INSERT INTO ' . $connection->quoteTableName($table)
. ' (' . implode(', ', $names) . ') VALUES ('
. implode(', ', $placeholders) . ')';
} else {
$sql .= ',(' . implode(', ', $placeholders) . ')';
}
$i++;
}
$command = Yii::app()->db->createCommand($sql);
return $command->execute($params);
}
}
从v1.1.14开始,CDbCommandBuilder类的方法createMultipleInsertCommand可用。从v1.1.14开始,CDbCommandBuilder类的方法createMultipleInsertCommand可用。不,从我花在它上面的时间来看,在Yii中没有什么可以做的,你现在做这件事的方式很可能是唯一的选择——我想知道是否有替代方案。我想你可以在的公认答案中找到你的解决方案。好吧,事实证明我真正需要的是使用事务。在foreach循环中保存400个模型:25秒。将foreach循环包装在beginTransaction&commit中:0.36秒。不,从我花费的时间来看,在Yii中没有什么可以做的,你现在做这件事的方式很可能是唯一的选择——我想知道是否有替代方案。我想你可以在的公认答案中找到你的解决方案。好吧,事实证明我真正需要的是使用事务。在foreach循环中保存400个模型:25秒。在beginTransaction&commit中包装foreach循环:0.36秒。回答得很好,节省时间:@AwaisUsmani这很有趣。仍然是yii版本1的用户!;-维护一个旧系统非常好的回答它拯救我的一天:@AwaisUsmani这很有趣。仍然是yii版本1的用户!;-维持旧制度