Ответ
Для работы с SQL-совместимыми базами данных в Go используется стандартный пакет database/sql
. Он предоставляет общий интерфейс, а для каждой конкретной СУБД требуется соответствующий драйвер.
Пример работы с PostgreSQL:
package main
import (
"database/sql"
"fmt"
"log"
// Пустой импорт _ для регистрации драйвера PostgreSQL.
// Драйвер зарегистрирует себя в пакете database/sql через свою init() функцию.
_ "github.com/lib/pq"
)
const connStr = "user=postgres dbname=mydb password=secret host=db.example.com port=5432 sslmode=disable"
func main() {
// sql.Open не устанавливает соединение сразу, а лишь готовит объект для работы с БД.
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("Ошибка при подготовке к подключению к БД: %v", err)
}
// defer db.Close() гарантирует, что пул соединений будет закрыт при выходе из main.
defer db.Close()
// db.Ping() проверяет реальное подключение к базе данных.
if err = db.Ping(); err != nil {
log.Fatalf("Ошибка подключения к БД: %v", err)
}
fmt.Println("Успешное подключение к PostgreSQL!")
// Выполнение запроса и обработка результатов
rows, err := db.Query("SELECT id, name FROM users WHERE id > $1", 0)
if err != nil {
log.Fatalf("Ошибка выполнения запроса: %v", err)
}
defer rows.Close()
for rows.Next() {
var id int
var name string
if err := rows.Scan(&id, &name); err != nil {
log.Printf("Ошибка сканирования строки: %v", err)
continue
}
fmt.Printf("ID: %d, Name: %sn", id, name)
}
if err := rows.Err(); err != nil {
log.Fatalf("Ошибка при итерации по результатам: %v", err)
}
}
Ключевые моменты:
- Пакет
database/sql
: Предоставляет абстракцию для работы с БД. Вы работаете с типамиsql.DB
,sql.Rows
и т.д. - Драйвер СУБД: Для каждой БД (PostgreSQL, MySQL, SQLite) нужен свой драйвер. Он импортируется с пустым идентификатором (
_
), чтобы выполнилась его функцияinit()
для регистрации вdatabase/sql
. - Пул соединений:
sql.DB
— это не одно соединение, а потокобезопасный пул соединений. Не нужно открывать и закрывать его для каждого запроса. Инициализируйте его один раз и используйте в течение жизни приложения. - Обработка ошибок: Всегда проверяйте ошибки после каждой операции с БД, включая
rows.Close()
и итерациюrows.Next()
(черезrows.Err()
). - Подготовленные выражения (Prepared Statements): Для защиты от SQL-инъекций и повышения производительности повторяющихся запросов используйте
db.Prepare()
иstmt.Exec()
/stmt.Query()
.