thinkphp 里面的 批量更新saveAll 用的是replace 我现在使用webman 引入 thinkOrm4.0一直有问题,其他未指定的数据也会更新成为默认值,不知道其他版本有没有问题
ps: 先解释一下 replace,这个是insert 和update 的结合体,他会根据主键更新,找不到是插入数据,这个是mysql 的原生语法
决定自己更新补充thinkOrm的语法
1,添加自定义文件,这个是核心
这里解释一下面是什么,就是根据传过来的数据,拼接成sql 语句,用 Db::execute 执行了。
SET sort = CASE id WHEN 1 THEN 11 WHEN 2 THEN 12 WHEN 3 THEN 12 END, score = CASE id WHEN 1 THEN 90 WHEN 2 THEN 85 WHEN 3 THEN 95 END
WHERE id IN (1, 2, 3);
<?phpnamespace app\db;use think\db\Query;
use think\facade\Db;class MyQuery extends Query
{public function batchUpdate(array $data, string $idField = 'id'):bool{if (empty($data)) return false; $table=$this->getTable();// 提取更新字段(排除主键) $fields = array_filter(array_keys($data[0]), fn($k) => $k !== $idField); // 构建每个字段的 CASE WHEN 语句 $cases = []; $ids = []; foreach ($fields as $field) { $case = "$field = CASE $idField"; foreach ($data as $row) { $id = (int)$row[$idField]; $value = is_string($row[$field]) ? "'" . addslashes($row[$field]) . "'" : $row[$field]; $case .= " WHEN $id THEN $value"; $ids[] = $id; } $case .= " END"; $cases[] = $case; } // 去重主键值 $ids = array_unique($ids); // 拼接完整 SQL $sql = "UPDATE $table SET \n " . implode(",\n ", $cases) . " WHERE $idField IN (" . implode(', ', $ids) . ");"; return Db::execute($sql);}
}
2,修改 orm配置文件
<?phpreturn ['auto_timestamp' => true,'default' => 'mysql','connections' => ['mysql' => [// 自定义查询类,这个是添加的'query' => '\app\db\MyQuery',],],
];
3,在使用位置使用
$ar=[['id'=>1,'sort'=>11,'score'=>90,],['id'=>2,'sort'=>12,'score'=>95,]
];
$goods_cate=new GoodsCateModel();
$info=$goods_cate->batchUpdate($ar);