如何在 CakePHP 3 中实现 INSERT ON DUPLICATE KEY UPDATE aka upsert?

Posted

技术标签:

【中文标题】如何在 CakePHP 3 中实现 INSERT ON DUPLICATE KEY UPDATE aka upsert?【英文标题】:How to implement INSERT ON DUPLICATE KEY UPDATE aka upsert in CakePHP 3? 【发布时间】:2022-01-14 10:37:43 【问题描述】:

我正在使用 Cakephp 3 和 mysql

我想通过CakePHP 3 模型实现INSERT on DUPLICATE KEY UPDATE 又名upsert 查询。

给定下表:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  17 |
|  3 | Sally    |  23 |
+----+----------+-----+

其中id 是主键,username 是唯一索引

当我有以下值等待更新时:

Felicia, 27
Timmy, 71

我希望 upsert 之后得到以下结果:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  71 |
|  3 | Sally    |  23 |
|  4 | Felicia  |  27 |
+----+----------+-----+

我知道如何在 MySQL 查询中进行 upsert:

INSERT INTO `users` (`username`, `age`) 
VALUES ('Felicia', 27), ('Timmy', 71) 
ON DUPLICATE KEY UPDATE 
`username`=VALUES(`username`),`age`=VALUES(`age`);

我知道如何在 CakePHP3 的多个查询中做到这一点。

   $newUsers = [
        [
            'username' => 'Felicia',
            'age' => 27,
        ],
        [
            'username' => 'Timmy',
            'age' => 71,
        ],
    ];

    foreach ($newUsers as $newUser) 
        $existingRecord = $this->Users->find()
            ->select(['id'])
            ->where(['username' => $newUser['username']])
            ->first();

        if (empty($existingRecord)) 
            $insertQuery = $this->Users->query();
            $insertQuery->insert(array_keys($newUser))
                ->values($newUser)
                ->execute();
         else 
            $updateQuery = $this->Users->query();
            $updateQuery->update()
                ->set($newUser)
                ->where(['id' => $existingRecord->id])
                ->execute();
        
    

我想知道的是:

有没有办法在单行中使用 CakePHP 3 进行 upsert,即使我使用链接?

请告知我该如何实施。

【问题讨论】:

*** 不是代码编写服务。请发布您迄今为止尝试过的内容以及遇到的问题。 CakePHP 3.0: How to do an insert on duplicate key update? 的可能重复项 只是为了澄清:它没有重复 [CakePHP 3.0:如何在重复键更新时插入?][1] [1]:***.com/questions/24852904/… @Dirk 你没有澄清任何事情,你只是在发表声明。想解释一下为什么你认为它不是重复的吗? @TomaszKowalczyk 现在好点了吗? 【参考方案1】:

使用https://***.com/a/24990944/80353 提供的答案,我想使用问题中给出的代码示例重新表述。

对以下记录运行 upsert

Felicia, 27
Timmy, 71

进入这张表

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  17 |
|  3 | Sally    |  23 |
+----+----------+-----+

最好的写法是

$newUsers = [
    [
        'username' => 'Felicia',
        'age' => 27,
    ],
    [
        'username' => 'Timmy',
        'age' => 71,
    ],
];

$columns = array_keys($newUsers[0]);

$upsertQuery = $this->Users->query();

$upsertQuery->insert($columns);

// need to run clause('values') AFTER insert()
$upsertQuery->clause('values')->values($newUsers);

$upsertQuery->epilog('ON DUPLICATE KEY UPDATE `username`=VALUES(`username`), `age`=VALUES(`age`)')
                ->execute();

查看this 了解有关epilog 的详细信息

查看this 了解如何在单个查询中写入插入多条记录的详细信息

【讨论】:

以上是关于如何在 CakePHP 3 中实现 INSERT ON DUPLICATE KEY UPDATE aka upsert?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C# 中实现 3 层架构

Cakephp 3.5 多次保存相同的记录

如何在 cakephp 中保存继承的对象

Cakephp 3 - 使用_joinData属于ToMany

Cakephp 3 先保存翻译。之后的原始实体

外文转译:通过楼梯到T-SQL DML等级3:在SQL Server中实现关系模型