Php 如何强制laravel在sync()方法中执行批处理(多次)插入?
当我使用Php 如何强制laravel在sync()方法中执行批处理(多次)插入?,php,laravel,Php,Laravel,当我使用sync()方法时,laravel会在我的中间表中执行许多单独的insert查询,如下所示: INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '60') INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '61') INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '60'), ('
sync()
方法时,laravel会在我的中间表中执行许多单独的insert查询,如下所示:
INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '60')
INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '61')
INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '60'), ('59', '61')
我希望它能像这样进行一次多次插入:
INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '60')
INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '61')
INSERT INTO `tag_user` (`user_id`, `tag_id`) VALUES ('59', '60'), ('59', '61')
可能吗?我正在使用MySql。最好有
attach()
方法,它将接受数组作为detach()
方法。有人这样做吗?是的,几天前我也在做同样的事情
eloquent在一个sql中执行多个插入
但要确保所有循环都是相等的列和字段,我第一次尝试删除一个没有值的循环,mysql将无法工作
例如:
但如果您想更新现有记录,则需要执行原始查询
例如:
我们的目标是回报像这样的东西
$keyString // (name, email, bla, bla)
$valString // ('john doe', 'email@email.com', 'bla', 'bla'), ('someone', 'email@email.com', 'bla', 'bla'),
确保使用数组计数来检查是否是逗号的最后一个数组
例如:
这需要重构我就是这样解决的: 我的模型 在我的应用程序中,每个用户都有许多标签(多对多关系)。它被称为数据库模式。 我的用户表称为“用户”,标签表称为“标签”。中间表称为“tag_user”,它有“tag_id”和“user_id”列 用户模型:
class User extends \Eloquent
{
public static $timestamps = false;
public function tags()
{
return $this->has_many_and_belongs_to('Models\Tag');
}
}
标签型号:
class Tag extends \Eloquent
{
public static $timestamps = false;
}
如何替换sync()
方法
这就是我使用多重插入强制laravel执行sync()
方法的方式:
//$currentUser is a model loaded from database
//Like this: $currentUser = Auth::user();
$newLinks = array();
$idsToSync = array();
foreach ($tags as $tag)
{
array_push($idsToSync, $tag->id);
}
//$currentUser->tags()->sync($idsToSync);
$currentIds = $currentUser->tags()->pivot()->lists('tag_id');
$idsToAttach = array_diff($idsToSync, $currentIds);
foreach ($idsToAttach as $value)
{
$newLink = array(
'user_id' => $currentUser->id,
'tag_id' => $value
);
$newLinks[] = $newLink;
}
if (count($newLinks) > 0)
{
\DB::table('tag_user')->insert($newLinks);
}
$idsToDetach = array_diff($currentIds, $idsToSync);
if (count($idsToDetach) > 0)
{
$currentUser->tags()->detach($idsToDetach);
}
此代码执行一次多插入而不是多次单插入。一种解决方法是使用Laravel的
DB::transaction()
并将同步作为一个闭包放入其中。您确定吗?默认情况下,它会这样做。一切都会按照您的需要转换为批处理模式。正如您所看到的,它通过foreach循环通过attach()
方法进行单次插入。谢谢您的回答。)但我有一个稍微不同的问题。
class Tag extends \Eloquent
{
public static $timestamps = false;
}
//$currentUser is a model loaded from database
//Like this: $currentUser = Auth::user();
$newLinks = array();
$idsToSync = array();
foreach ($tags as $tag)
{
array_push($idsToSync, $tag->id);
}
//$currentUser->tags()->sync($idsToSync);
$currentIds = $currentUser->tags()->pivot()->lists('tag_id');
$idsToAttach = array_diff($idsToSync, $currentIds);
foreach ($idsToAttach as $value)
{
$newLink = array(
'user_id' => $currentUser->id,
'tag_id' => $value
);
$newLinks[] = $newLink;
}
if (count($newLinks) > 0)
{
\DB::table('tag_user')->insert($newLinks);
}
$idsToDetach = array_diff($currentIds, $idsToSync);
if (count($idsToDetach) > 0)
{
$currentUser->tags()->detach($idsToDetach);
}