BudiBadu Logo

Samplebadu

Code with Example
BudiBadu Logo
Samplebadu

Go by Example: ORM with GORM

Go 1.23

Simplify database interactions with GORM, a developer-friendly ORM for Go. This example covers defining models, performing auto-migrations, and executing CRUD (Create, Read, Update, Delete) operations with a fluent API.

Code

package main

import (
    "fmt"
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

type Product struct {
    gorm.Model
    Code  string
    Price uint
}

func main() {
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    // Migrate the schema
    db.AutoMigrate(&Product{})

    // Create
    db.Create(&Product{Code: "D42", Price: 100})

    // Read
    var product Product
    db.First(&product, 1) // find product with integer primary key
    db.First(&product, "code = ?", "D42") // find product with code D42

    // Update - update product's price to 200
    db.Model(&product).Update("Price", 200)

    // Delete - delete product
    db.Delete(&product, 1)
    
    fmt.Println("GORM operations completed")
}

Explanation

GORM is a comprehensive Object-Relational Mapping (ORM) library for Go that drastically simplifies database interactions. It abstracts away raw SQL, allowing you to work with Go structs and methods. While powerful, GORM should be used with an understanding of its underlying behavior to avoid performance pitfalls like the "N+1 query problem".

Key Features & Best Practices:

  • Model Definition: Embed gorm.Model in your structs to automatically include standard fields like ID, CreatedAt, UpdatedAt, and DeletedAt (for soft deletes).
  • Tags: Use struct tags (e.g., gorm:"index;not null;default:'active'") to define schema constraints, indexes, and default values directly in your Go code.
  • Hooks: Leverage lifecycle hooks such as BeforeCreate or AfterSave to automate tasks like password hashing or data validation.
  • Transactions: Ensure data integrity by wrapping multiple operations in a transaction using db.Transaction(func(tx *gorm.DB) error { ... }).

Code Breakdown

9
Embedding gorm.Model is a best practice for most tables. It gives you a primary key (ID) and automatic timestamp tracking (CreatedAt, UpdatedAt) without writing boilerplate.
15
gorm.Open initializes the database session. GORM supports multiple drivers (SQLite, MySQL, Postgres). The &gorm.Config{} allows you to customize logging, naming strategies, and more.
21
db.AutoMigrate is a powerful feature that automatically creates or updates database tables to match your Go structs. It is safe to run on startup as it adds missing columns/indexes but won't delete existing data.
24
db.Create accepts a pointer to a struct. It generates the SQL INSERT statement and automatically populates the ID and CreatedAt fields in the struct after insertion.
28
db.First(&product, 1) fetches the first record ordered by primary key. It adds "LIMIT 1" to the SQL query. The second argument is the primary key value.
32
db.Model(&product).Update updates a single column. To update multiple columns, use Updates() with a map or struct. Note that Updates() with a struct will ignore zero values (like 0 or ""), so use a map for those.
35
db.Delete performs a soft delete if the model has a DeletedAt field (which gorm.Model does). The record remains in the DB but is ignored by normal queries. Use Unscoped().Delete() to remove it permanently.