database/sql: стандартный пакет
▸Подключение к PostgreSQL
1package main23import (4 "database/sql"5 "fmt"6 "log"78 _ "github.com/lib/pq"9)1011func main() {12 connStr := "user=postgres password=secret dbname=mydb sslmode=disable"13 db, err := sql.Open("postgres", connStr)14 if err != nil {15 log.Fatal(err)16 }17 defer db.Close()1819 // Проверка соединения20 if err := db.Ping(); err != nil {21 log.Fatal(err)22 }2324 fmt.Println("Connected to database")25}
▸Connection Pooling
1func main() {2 db, _ := sql.Open("postgres", connStr)34 // Настройка пула соединений5 db.SetMaxOpenConns(25)6 db.SetMaxIdleConns(5)7 db.SetConnMaxLifetime(5 * time.Minute)89 // Использование10 defer db.Close()11}
▸CRUD операции
1type User struct {2 ID int3 Name string4 Email string5}67// Создание8func CreateUser(db *sql.DB, name, email string) (int, error) {9 var id int10 err := db.QueryRow(11 "INSERT INTO users(name, email) VALUES($1, $2) RETURNING id",12 name, email,13 ).Scan(&id)14 return id, err15}1617// Чтение18func GetUser(db *sql.DB, id int) (*User, error) {19 user := &User{}20 err := db.QueryRow(21 "SELECT id, name, email FROM users WHERE id = $1", id,22 ).Scan(&user.ID, &user.Name, &user.Email)23 return user, err24}2526// Обновление27func UpdateUser(db *sql.DB, id int, name string) error {28 _, err := db.Exec(29 "UPDATE users SET name = $1 WHERE id = $2", name, id,30 )31 return err32}3334// Удаление35func DeleteUser(db *sql.DB, id int) error {36 _, err := db.Exec("DELETE FROM users WHERE id = $1", id)37 return err38}
▸Пакетные запросы
1func GetAllUsers(db *sql.DB) ([]User, error) {2 rows, err := db.Query("SELECT id, name, email FROM users")3 if err != nil {4 return nil, err5 }6 defer rows.Close()78 var users []User9 for rows.Next() {10 var u User11 if err := rows.Scan(&u.ID, &u.Name, &u.Email); err != nil {12 return nil, err13 }14 users = append(users, u)15 }1617 return users, rows.Err()18}
sqlx: расширение
▸Установка
1go get github.com/jmoiron/sqlx
▸Использование
1import "github.com/jmoiron/sqlx"23func main() {4 db, _ := sqlx.Connect("postgres", connStr)56 // Автоматический маппинг7 var users []User8 db.Select(&users, "SELECT * FROM users WHERE active = $1", true)910 // Одна строка11 var user User12 db.Get(&user, "SELECT * FROM users WHERE id = $1", 1)1314 // Named queries15 query, args, _ := sqlx.In(16 "SELECT * FROM users WHERE id IN (?)",17 []int{1, 2, 3},18 )19 db.Select(&users, query, args...)20}
GORM: ORM
▸Определение моделей
1import (2 "gorm.io/driver/postgres"3 "gorm.io/gorm"4)56type User struct {7 gorm.Model8 Name string9 //gorm:"uniqueIndex"10 Email string11 Orders []Order12}1314type Order struct {15 gorm.Model16 UserID uint17 Amount float6418}1920func main() {21 dsn := "host=localhost user=postgres password=secret dbname=mydb port=5432 sslmode=disable"22 db, _ := gorm.Open(postgres.Open(dsn), &gorm.Config{})2324 // Автоматическая миграция25 db.AutoMigrate(&User{}, &Order{})26}
▸CRUD в GORM
1// Создание2user := User{Name: "Alice", Email: "alice@test.com"}3result := db.Create(&user)45// Чтение6var user User7db.First(&user, 1) // По ID8db.Where("name = ?", "Alice").First(&user) // По условию910// Обновление11db.Model(&user).Update("Name", "Bob")1213// Удаление14db.Delete(&user, 1)
▸Ассоциации
1// Создание с ассоциациями2user := User{3 Name: "Alice",4 Orders: []Order{5 {Amount: 100.50},6 {Amount: 200.75},7 },8}9db.Create(&user)1011// Preload (жадная загрузка)12var userWithOrders User13db.Preload("Orders").First(&userWithOrders, 1)
Миграции
▸golang-migrate
1# Создание миграции2migrate create -ext sql -dir db/migrations -seq create_users_table34# Применение5migrate -path db/migrations -database "postgres://localhost:5432/mydb?sslmode=disable" up67# Откат8migrate -path db/migrations -database "postgres://localhost:5432/mydb?sslmode=disable" down 1
▸SQL файл миграции
1-- 000001_create_users_table.up.sql2CREATE TABLE users (3 id SERIAL PRIMARY KEY,4 name VARCHAR(100) NOT NULL,5 email VARCHAR(255) UNIQUE NOT NULL,6 created_at TIMESTAMP DEFAULT NOW(),7 updated_at TIMESTAMP DEFAULT NOW()8);910-- 000001_create_users_table.down.sql11DROP TABLE IF EXISTS users;
Заключение
Go предоставляет мощные инструменты для работы с базами данных: от стандартного database/sql до полноценных ORM как GORM. Выбор зависит от сложности проекта и требований к гибкости запросов. На собеседовании важно понимать connection pooling, транзакции и типичные паттерны доступа к данным.