воскресенье, 31 мая 2020 г.

Работа с базами данных в Golang. Пакет database/sql в Golang

Пакет database/sql предоставляет общий интерфейс для баз данных SQL (или SQL-подобных).

Драйвер базы данных

Пакет database/sql должен использоваться вместе с драйвером базы данных.

В приведенном ниже описании предполагается, что драйвер был импортирован.

Подключение к базе данных

Open используется для создания дескриптора базы данных:

db, err := sql.Open(driver, dataSourceName)

Где driver указывает драйвер базы данных, а dataSourceName указывает информацию о подключении к базе данных, такую ​​как имя базы данных и учетные данные для аутентификации.

Обратите внимание, что Open не открывает соединение с базой данных напрямую: это откладывается до выполнения запроса. Чтобы убедиться, что соединение может быть установлено перед выполнением запроса, используйте метод PingContext:

if err := db.PingContext(ctx); err != nil {
    log.Fatal(err)
}

После использования база данных закрывается с помощью метода Close.

Выполнение запросов

ExecContext используется для запросов, где строки ответа (rows) не возвращаются:

result, err := db.ExecContext(ctx,
    "INSERT INTO users (name, age) VALUES ($1, $2)",
    "gopher",
    27,
)

Где result содержит идентификатор последней вставки и количество затронутых строк. Доступность этих значений зависит от драйвера базы данных.

QueryContext используется для поиска:

rows, err := db.QueryContext(ctx, "SELECT name FROM users WHERE age = $1", age)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
    var name string
    if err := rows.Scan(&name); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
    log.Fatal(err)
}

QueryRowContext используется там, где ожидается только одна строка ответа:

var age int64
err := db.QueryRowContext(ctx, "SELECT age FROM users WHERE name = $1", name).Scan(&age)

Подготовленные утверждения (statements) могут быть созданы с PrepareContext:

age := 27
stmt, err := db.PrepareContext(ctx, "SELECT name FROM users WHERE age = $1")
if err != nil {
    log.Fatal(err)
}
rows, err := stmt.Query(age)
// обработка строк ответа

ExecContext, QueryContext и QueryRowContext могут быть вызваны для утверждений (statements). После использования утверждение должно быть закрыто с помощью Close.

Транзакции

Транзакции начинаются с BeginTx:

tx, err := db.BeginTx(ctx, nil)
if err != nil {
    log.Fatal(err)
}

Уже описанные методы ExecContext, QueryContext, QueryRowContext и PrepareContext могут использоваться в транзакции.

Транзакция должна завершиться вызовом Commit или Rollback.

Работа с NULL

Если столбец базы данных обнуляется, один из типов, поддерживающих нулевые значения, должен быть передан в Scan.

Например, если столбец name в таблице names обнуляется:

var name sql.NullString
err := db.QueryRowContext(ctx, "SELECT name FROM names WHERE id = $1", id).Scan(&name)
...
if name.Valid {
    // используем name.String
} else {
    // значение равно NULL
}

В database/sql реализованы только NullBool, NullFloat64, NullInt64, NullInt32, NullString и NullTime. Реализации специфических для базы данных нулевых типов оставлены для драйвера базы данных. Пользовательские типы, поддерживающие NULL, могут быть созданы путем реализации интерфейсов database/sql/driver.Valuer и database/sql.Scanner.


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


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

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