code: public function upsert($table, $insertColumns, $updateColumns = true, $params = [])
      {
          $sql = $this->db->getQueryBuilder()->upsert($table, $insertColumns, $updateColumns, $params);
  
          return $this->setSql($sql)->bindValues($params);
      }
docs: Creates a command to insert rows into a database table if
  they do not already exist (matching unique constraints),
  or update them if they do.
  
  For example,
  
  ```php
  $sql = $queryBuilder->upsert('pages', [
  'name' => 'Front page',
  'url' => 'http://example.com/', // url is unique
  'visits' => 0,
  ], [
  'visits' => new \yii\db\Expression('visits + 1'),
  ], $params);
  ```
  
  The method will properly escape the table and column names.
  
  @param string $table the table that new rows will be inserted into/updated in.
  @param array|Query $insertColumns the column data (name => value) to be inserted into the table or instance
  of [[Query]] to perform `INSERT INTO ... SELECT` SQL statement.
  @param array|bool $updateColumns the column data (name => value) to be updated if they already exist.
  If `true` is passed, the column data will be updated to match the insert column data.
  If `false` is passed, no update will be performed if the column data already exists.
  @param array $params the parameters to be bound to the command.
  @return $this the command object itself.
  @since 2.0.14