🖥️ VS Code: Lihat Database Langsung dari Editor
Install extension SQLite Viewer (oleh Florian Klampfer) dari Extensions panel. Setelah GORM membuat file app.db (SQLite), kamu bisa klik file tersebut di sidebar VS Code dan melihat isi tabel langsung tanpa perlu tools eksternal. Untuk MySQL/PostgreSQL, coba extension Database Client (oleh cweijan).
GORM adalah ORM paling populer di ekosistem Go. Dengan GORM, kamu bisa berinteraksi dengan database (MySQL, PostgreSQL, SQLite) menggunakan struct Go tanpa menulis SQL manual untuk operasi standar.
Install GORM
# Install GORM
go get gorm.io/gorm
# Install driver database (pilih salah satu)
go get gorm.io/driver/sqlite # SQLite
go get gorm.io/driver/mysql # MySQL
go get gorm.io/driver/postgres # PostgreSQL
Connect ke Database
package main
import (
"gorm.io/driver/sqlite"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// SQLite (cocok untuk development/testing)
db, err := gorm.Open(sqlite.Open("app.db"), &gorm.Config{})
// MySQL
dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
// PostgreSQL
dsn := "host=localhost user=postgres password=secret dbname=mydb port=5432"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
panic("Gagal connect ke database: " + err.Error())
}
Definisi Model
type User struct {
gorm.Model // embed: ID, CreatedAt, UpdatedAt, DeletedAt (soft delete)
Nama string `gorm:"not null"`
Email string `gorm:"uniqueIndex;not null"`
Password string `gorm:"not null"`
Aktif bool `gorm:"default:true"`
Orders []Order // relasi HasMany
}
type Order struct {
gorm.Model
UserID uint // foreign key otomatis
Produk string `gorm:"not null"`
Harga float64
User User // relasi BelongsTo
}
// gorm.Model memberikan field:
// ID uint (auto increment primary key)
// CreatedAt time.Time
// UpdatedAt time.Time
// DeletedAt gorm.DeletedAt (soft delete)
AutoMigrate
// Buat/update tabel secara otomatis berdasarkan struct
err := db.AutoMigrate(&User{}, &Order{})
if err != nil {
panic(err)
}
// AutoMigrate hanya menambah kolom baru, tidak menghapus kolom yang ada
Create
user := User{
Nama: "Budi Santoso",
Email: "budi@email.com",
Password: "hashedpassword",
}
result := db.Create(&user)
if result.Error != nil {
fmt.Println("Error:", result.Error)
}
fmt.Println("ID baru:", user.ID) // ID terisi otomatis setelah Create
// Insert banyak sekaligus
users := []User{
{Nama: "Alice", Email: "alice@email.com", Password: "pass1"},
{Nama: "Bob", Email: "bob@email.com", Password: "pass2"},
}
db.Create(&users)
Read
// Ambil satu record — First, Last, Take
var user User
db.First(&user, 1) // by primary key
db.First(&user, "email = ?", "budi@email.com")
// Ambil semua
var users []User
db.Find(&users)
db.Find(&users, "aktif = ?", true)
// Where
db.Where("nama LIKE ?", "%Budi%").Find(&users)
db.Where("aktif = ? AND umur > ?", true, 20).Find(&users)
// Order, Limit, Offset
db.Order("created_at desc").Limit(10).Offset(0).Find(&users)
// Select kolom tertentu
db.Select("id", "nama", "email").Find(&users)
// Count
var total int64
db.Model(&User{}).Where("aktif = ?", true).Count(&total)
// Cek record tidak ditemukan
result := db.First(&user, 999)
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
fmt.Println("User tidak ditemukan")
}
Update
// Update satu field
db.Model(&user).Update("nama", "Budi Santoso Jr.")
// Update banyak field dengan struct (zero value diabaikan)
db.Model(&user).Updates(User{Nama: "Nama Baru", Aktif: true})
// Update dengan map (zero value tetap diupdate)
db.Model(&user).Updates(map[string]interface{}{
"nama": "Nama Baru",
"aktif": false,
})
// Update berdasarkan kondisi
db.Model(&User{}).Where("aktif = ?", false).Update("nama", "Inactive User")
Delete (Soft Delete & Hard Delete)
// Soft delete (karena User embed gorm.Model)
// Hanya mengisi DeletedAt, record tidak benar-benar terhapus
db.Delete(&user, 1)
// Query otomatis mengecualikan yang sudah soft-deleted
db.Find(&users) // tidak termasuk yang deleted
// Temukan yang sudah di-delete
db.Unscoped().Find(&users)
// Hard delete (permanent)
db.Unscoped().Delete(&user, 1)
Relasi
// Preload — eager loading relasi
var user User
db.Preload("Orders").First(&user, 1)
fmt.Println(user.Orders) // orders sudah terisi
// Preload bersyarat
db.Preload("Orders", "harga > ?", 100000).Find(&users)
// Buat record dengan relasi
user := User{
Nama: "Sari",
Email: "sari@email.com",
Orders: []Order{
{Produk: "Laptop", Harga: 15000000},
{Produk: "Mouse", Harga: 250000},
},
}
db.Create(&user) // user + orders dibuat sekaligus
// Joins (SQL JOIN)
db.Joins("Orders").Find(&users)
- Selalu cek
result.Errorsetelah operasi database - Gunakan
db.Debug()untuk melihat query SQL yang dihasilkan - Untuk performa, gunakan
Selectdan hanya ambil kolom yang dibutuhkan - Gunakan transaksi (
db.Transaction) untuk operasi multi-step yang harus atomic
Komentar 0