воскресенье, 5 сентября 2021 г.

Использование подготовленных операторов с пакетом database/sql в Golang

Вы можете определить подготовленный оператор для повторного использования. Это может помочь вашему коду работать немного быстрее, избегая накладных расходов на повторное создание оператора каждый раз, когда ваш код выполняет операцию с базой данных.

Примечание. Заполнители параметров в подготовленных операторах различаются в зависимости от СУБД и драйвера, который вы используете. Например, драйвер pq для Postgres требует заполнителя типа $1 вместо ?.

Что такое подготовленный оператор?

Подготовленный оператор - это SQL, который анализируется и сохраняется СУБД, обычно содержащий заполнители, но без фактических значений параметров. Позже оператор может быть выполнен с набором значений параметров.

Как использовать подготовленный оператор

Если вы планируете выполнять один и тот же SQL несколько раз, вы можете использовать sql.Stmt, чтобы заранее подготовить оператор SQL, а затем выполнить его по мере необходимости.

В следующем примере создается подготовленный оператор, который выбирает конкретный альбом из базы данных. DB.Prepare возвращает sql.Stmt, представляющий подготовленный оператор для данного текста SQL. Вы можете передать параметры для оператора SQL в Stmt.Exec, Stmt.QueryRow или Stmt.Query для запуска оператора.

// AlbumByID получает указанный альбом.
func AlbumByID(id int) (Album, error) {
    // Определяем подготовленный оператор. 
    // Обычно стоит определять оператор
    // в другом месте и сохранять его 
    // для использования в таких функциях, как эта.
    stmt, err := db.Prepare("SELECT * FROM album WHERE id = ?")
    if err != nil {
        log.Fatal(err)
    }

    var album Album

    // Выполняем подготовленный оператор, 
    // передавая значение id для параметра, 
    // заполнитель которого - ?
    err := stmt.QueryRow(id).Scan(&album.ID, &album.Title, 
        &album.Artist, &album.Price, &album.Quantity)
    if err != nil {
        if err == sql.ErrNoRows {
            // Обработка случая отсутствия возвращенных строк.
        }
        return album, err
    }
    return album, nil
}

Поведение подготовленного оператора

Подготовленный sql.Stmt предоставляет обычные методы Exec, QueryRow и Query для вызова оператора.

Однако, поскольку sql.Stmt уже представляет предустановленный оператор SQL, его методы Exec, QueryRow и Query принимают только значения параметров SQL, соответствующие заполнителям, опуская текст SQL.

Вы можете определить новый sql.Stmt по-разному, в зависимости от того, как вы его будете использовать.

  • DB.Prepare и DB.PrepareContext создают подготовленный оператор, который может выполняться изолированно, вне транзакции, как это делают DB.Exec и DB.Query.
  • Tx.Prepare, Tx.PrepareContext, Tx.Stmt и Tx.StmtContext создают подготовленный оператор для использования в конкретной транзакции. Prepare и PrepareContext используют текст SQL для определения оператора. Stmt и StmtContext используют результат DB.Prepare или DB.PrepareContext. То есть они преобразуют sql.Stmt не для транзакций в sql.Stmt для этой транзакции.
  • Conn.PrepareContext создает подготовленный оператор из sql.Conn, который представляет зарезервированное соединение.

Убедитесь, что stmt.Close вызывается, когда ваш код завершает работу с оператором. Это освободит все ресурсы базы данных (например, подлежащие соединения), которые могут быть с ней связаны. Для операторов, которые являются только локальными переменными в функции, достаточно defer stmt.Close().

Функции для создания подготовленного оператора

DB.Prepare, DB.PrepareContext - Подготовливает оператор для изолированного выполнения, иначе он будет преобразован в подготовленный оператор внутри транзакции с помощью Tx.Stmt.

Tx.Prepare, Tx.PrepareContext, Tx.Stmt, Tx.StmtContext - Подготавливает оператор для использования в конкретной транзакции.

Conn.PrepareContext - Для использования с зарезервированными соединениями.


Читайте также:


Купить gopher

Комментариев нет:

Отправить комментарий