Nyx*_*nyx 10 php mysql laravel
是否有一个快速的方法来修改生成的SQL查询Laravel的流利有一个INSERT IGNORE
,而不是通常的INSERT
?
我正在尝试插入一个包含50个元素的数组.手动写出整个查询会使代码膨胀并使其更容易受到人为错误的影响.
mal*_*hal 13
在你的模型中试试这个魔法:
public static function insertIgnore($array){
$a = new static();
if($a->timestamps){
$now = \Carbon\Carbon::now();
$array['created_at'] = $now;
$array['updated_at'] = $now;
}
DB::insert('INSERT IGNORE INTO '.$a->table.' ('.implode(',',array_keys($array)).
') values (?'.str_repeat(',?',count($array) - 1).')',array_values($array));
}
Run Code Online (Sandbox Code Playgroud)
使用这样:
Shop::insertIgnore(array('name' => 'myshop'));
Run Code Online (Sandbox Code Playgroud)
如果'name'属性是唯一键,这是防止first-orCrate在多用户环境中可能发生的约束违规的好方法.
我无法像拉斯蒂斯拉夫的回答中建议的那样修补猴子。
这对我有用:
compileInsert
自定义查询语法类中的重写方法,该类扩展了框架的MySqlGrammar类。
通过setQueryGrammar
从数据库连接实例中调用方法来使用此自定义语法类的实例。
因此,类代码如下所示:
<?php
namespace My\Namespace;
use Illuminate\Database\Query\Builder;
use Illuminate\Database\Query\Grammars\MySqlGrammar;
/**
* Changes "INSERT" to "INSERT IGNORE"
*/
class CustomMySqlGrammar extends MySqlGrammar
{
/**
* Compile an insert statement into SQL.
*
* @param \Illuminate\Database\Query\Builder $query
* @param array $values
* @return string
*/
public function compileInsert(Builder $query, array $values)
{
// Essentially we will force every insert to be treated as a batch insert which
// simply makes creating the SQL easier for us since we can utilize the same
// basic routine regardless of an amount of records given to us to insert.
$table = $this->wrapTable($query->from);
if (! is_array(reset($values))) {
$values = [$values];
}
$columns = $this->columnize(array_keys(reset($values)));
// We need to build a list of parameter place-holders of values that are bound
// to the query. Each insert should have the exact same amount of parameter
// bindings so we will loop through the record and parameterize them all.
$parameters = collect($values)->map(function ($record) {
return '('.$this->parameterize($record).')';
})->implode(', ');
return "insert ignore into $table ($columns) values $parameters";
}
}
Run Code Online (Sandbox Code Playgroud)
我compileInsert
从框架的类复制了方法,然后在方法内部,我仅更改insert
为insert ignore
。其他所有内容均保持不变。
然后,在特定的代码点中,在需要“插入忽略”的应用程序中(预定任务),我只需完成以下操作:
<?php
use DB;
use My\Namespace\CustomMySqlGrammar;
class SomeClass
{
public function someMethod()
{
// Changes "INSERT" to "INSERT IGNORE"
DB::connection()->setQueryGrammar(new CustomMySqlGrammar());
// et cetera... for example:
ModelClass::insert($data);
}
}
Run Code Online (Sandbox Code Playgroud)
对于这项工作,您需要创建一个新的语法,其中包含正确的字符串:
语法.php (1)
语法是连接的公共属性,DB
或者在本例中是Database
存储连接的公共属性。这并不是很直接,但从属性的可见性来看,您应该能够将特殊语法注入到数据库层中。
我还建议您在项目中提出这个问题,他们可能有更好的想法,如何使此类案例更加灵活。
(1)这是以前的答案参考日期。如果你今天看到这个,你需要采用你使用的 Laravel 版本,例如Grammar.php for 4.0,这些类已移至laravel/framework
.
归档时间: |
|
查看次数: |
18815 次 |
最近记录: |