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

Kim*_*cks 3 mysql cakephp upsert insert-update cakephp-3.0

我正在使用 CakePHP 3 和 MySQL。

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

鉴于下表:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  17 |
|  3 | Sally    |  23 |
+----+----------+-----+
Run Code Online (Sandbox Code Playgroud)

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

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

Felicia, 27
Timmy, 71
Run Code Online (Sandbox Code Playgroud)

我希望在 upsert得到以下结果:

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  71 |
|  3 | Sally    |  23 |
|  4 | Felicia  |  27 |
+----+----------+-----+
Run Code Online (Sandbox Code Playgroud)

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

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

我知道如何在 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();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我想知道的是:

即使我使用链接,有没有办法在一行中使用 CakePHP 3 进行更新插入?

请告知我如何实施。

Kim*_*cks 6

使用/sf/answers/1749366111/ 上提供的答案,我想使用问题中给出的代码示例对其进行重新表述。

对以下记录运行 upsert

Felicia, 27
Timmy, 71
Run Code Online (Sandbox Code Playgroud)

进入这张桌子

+----+----------+-----+
| id | username | age |
+----+----------+-----+
|  1 | admin    |  33 |
|  2 | Timmy    |  17 |
|  3 | Sally    |  23 |
+----+----------+-----+
Run Code Online (Sandbox Code Playgroud)

最好的方法是把它写成

$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();
Run Code Online (Sandbox Code Playgroud)

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

检查出以了解如何编写插入在单个查询多个记录