Настройка GORM для Go веб-застосунку
GORM — найпопулярніший ORM для Go. Не намагається цілком приховати SQL, надаючи прямий доступ до raw запитів де це потрібно. Версія v2 несумісна з v1 за API.
go get gorm.io/gorm
go get gorm.io/driver/postgres
Ініціалізація
package db
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"log"
"time"
)
func New(dsn string) (*gorm.DB, error) {
db, err := gorm.Open(postgres.New(postgres.Config{
DSN: dsn,
PreferSimpleProtocol: true,
}), &gorm.Config{
Logger: logger.Default.LogMode(logger.Warn),
NowFunc: func() time.Time { return time.Now().UTC() },
})
sqlDB, _ := db.DB()
sqlDB.SetMaxOpenConns(25)
sqlDB.SetMaxIdleConns(10)
sqlDB.SetConnMaxLifetime(5 * time.Minute)
return db, err
}
Моделі
type Product struct {
ID uint `gorm:"primarykey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
Title string `gorm:"type:varchar(500);not null"`
Slug string `gorm:"type:varchar(520);uniqueIndex"`
Price float64 `gorm:"type:decimal(12,2)"`
Status ProductStatus `gorm:"type:varchar(20);default:draft"`
CategoryID uint `gorm:"not null;index"`
Category Category `gorm:"foreignKey:CategoryID;constraint:OnDelete:RESTRICT"`
Tags []Tag `gorm:"many2many:product_tags;"`
}
func (Product) TableName() string {
return "products"
}
Запити
type ProductRepository struct {
db *gorm.DB
}
func (r *ProductRepository) GetPublished(
ctx context.Context,
categoryID uint,
limit, offset int,
) ([]Product, error) {
var products []Product
err := r.db.WithContext(ctx).
Preload("Category").
Preload("Tags").
Where("category_id = ? AND status = ?", categoryID, "published").
Order("created_at DESC").
Limit(limit).
Offset(offset).
Find(&products).Error
return products, err
}
Міграції
Використовуємо golang-migrate для production:
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
migrate create -ext sql -dir migrations -seq create_products
Терміни
Первісна настройка GORM з golang-migrate: 1 день.







