Pelajari teknik advanced update di GORM seperti Update with SQL Expression, Update from SubQuery, Without Hooks/Time Tracking, Returning Data From Modified Rows, Check Field has Changed?, dan Change Updating Values dalam Golang. Dilengkapi dengan contoh kode dan unit test.
GORM memiliki berbagai fitur update data yang lebih kompleks dan canggih. Artikel ini akan membahas teknik advanced update seperti Update with SQL Expression, Update from SubQuery, Without Hooks/Time Tracking, Returning Data From Modified Rows, Check Field has Changed?, dan Change Updating Values.
1. Update with SQL Expression
Contoh Implementasi
// UpdateWithExpression menggunakan ekspresi SQL untuk memperbarui nilai tertentu
func UpdateWithExpression(db *gorm.DB, id uint) error {
return db.Model(&User{}).Where("id = ?", id).Update("balance", gorm.Expr("balance + ?", 100)).Error
}
Penjelasan Kode
UpdateWithExpression
menggunakangorm.Expr
untuk menambahkan 100 ke kolombalance
.Where("id = ?", id)
memastikan hanya user dengan ID tertentu yang diperbarui.
Unit Test
func TestUpdateWithExpression(t *testing.T) {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
user := User{Balance: 500}
db.Create(&user)
err := UpdateWithExpression(db, user.ID)
if err != nil {
t.Errorf("Update gagal: %v", err)
}
var updatedUser User
db.First(&updatedUser, user.ID)
if updatedUser.Balance != 600 {
t.Errorf("Expected balance 600, got %d", updatedUser.Balance)
}
}
Penjelasan Kode Unit Test
- Membuka koneksi database SQLite dan memastikan tabel
User
tersedia. - Menambahkan user dengan saldo awal 500.
- Memanggil
UpdateWithExpression
untuk menambahkan 100 ke saldo. - Mengecek apakah saldo yang diperbarui sesuai dengan ekspektasi.
2. Update from SubQuery
Contoh Implementasi
// UpdateFromSubQuery memperbarui data berdasarkan hasil subquery
func UpdateFromSubQuery(db *gorm.DB) error {
subQuery := db.Table("users").Select("MAX(balance)")
return db.Model(&User{}).Where("balance < ?", subQuery).Update("status", "inactive").Error
}
Penjelasan Kode
subQuery
mengambil nilaibalance
tertinggi.Where("balance < ?", subQuery)
memilih user dengan saldo di bawah nilai maksimum.Update("status", "inactive")
mengubah status user menjadi “inactive”.
Unit Test
func TestUpdateFromSubQuery(t *testing.T) {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
users := []User{
{Balance: 500, Status: "active"},
{Balance: 1000, Status: "active"},
}
db.Create(&users)
err := UpdateFromSubQuery(db)
if err != nil {
t.Errorf("Update gagal: %v", err)
}
var count int64
db.Model(&User{}).Where("status = ?", "inactive").Count(&count)
if count != 1 {
t.Errorf("Expected 1 user inactive, got %d", count)
}
}
Penjelasan Kode Unit Test
- Membuka koneksi database SQLite dan memastikan tabel
User
tersedia. - Menambahkan dua user dengan saldo berbeda.
- Memanggil
UpdateFromSubQuery
untuk menonaktifkan user dengan saldo lebih kecil. - Mengecek apakah satu user benar-benar dinonaktifkan.
3. Without Hooks/Time Tracking
Contoh Implementasi
// UpdateWithoutHooks memperbarui data tanpa menjalankan hooks atau tracking waktu
func UpdateWithoutHooks(db *gorm.DB, id uint) error {
return db.Model(&User{}).Where("id = ?", id).UpdateColumn("balance", 1000).Error
}
Penjelasan Kode
UpdateColumn("balance", 1000)
memperbarui saldo tanpa menjalankan hooks atau tracking waktu.
Unit Test
func TestUpdateWithoutHooks(t *testing.T) {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
user := User{Balance: 500}
db.Create(&user)
err := UpdateWithoutHooks(db, user.ID)
if err != nil {
t.Errorf("Update gagal: %v", err)
}
var updatedUser User
db.First(&updatedUser, user.ID)
if updatedUser.Balance != 1000 {
t.Errorf("Expected balance 1000, got %d", updatedUser.Balance)
}
}
Penjelasan Kode Unit Test
- Membuka koneksi database SQLite dan memastikan tabel
User
tersedia. - Menambahkan user dengan saldo awal 500.
- Memanggil
UpdateWithoutHooks
untuk memperbarui saldo tanpa hooks. - Mengecek apakah saldo yang diperbarui sesuai dengan ekspektasi.
4. Returning Data From Modified Rows
Contoh Implementasi
// UpdateReturningData memperbarui data dan mengembalikan data yang diperbarui
func UpdateReturningData(db *gorm.DB, id uint) (User, error) {
var user User
err := db.Model(&User{}).Where("id = ?", id).Update("balance", 1500).Returning("*").Scan(&user).Error
return user, err
}
Penjelasan Kode
Update("balance", 1500)
memperbarui saldo menjadi 1500.Returning("*")
mengembalikan seluruh data user setelah diperbarui.Scan(&user)
menyimpan hasil update ke dalam structuser
.
Unit Test
func TestUpdateReturningData(t *testing.T) {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
user := User{Balance: 1000}
db.Create(&user)
updatedUser, err := UpdateReturningData(db, user.ID)
if err != nil {
t.Errorf("Update gagal: %v", err)
}
if updatedUser.Balance != 1500 {
t.Errorf("Expected balance 1500, got %d", updatedUser.Balance)
}
}
Penjelasan Kode Unit Test
- Membuka koneksi database SQLite dan memastikan tabel
User
tersedia. - Menambahkan user dengan saldo awal 1000.
- Memanggil
UpdateReturningData
untuk memperbarui saldo dan mendapatkan hasilnya. - Mengecek apakah saldo yang diperbarui sesuai dengan ekspektasi.
5. Check Field has Changed?
Contoh Implementasi
// HasFieldChanged mengecek apakah suatu field telah berubah
func HasFieldChanged(db *gorm.DB, id uint) (bool, error) {
var user User
db.First(&user, id)
return db.Model(&user).Updates(User{Balance: 2000}).RowsAffected > 0, nil
}
Penjelasan Kode
db.First(&user, id)
mengambil data user berdasarkan ID.Updates(User{Balance: 2000})
memperbarui saldo.RowsAffected > 0
mengecek apakah pembaruan terjadi.
Unit Test
func TestHasFieldChanged(t *testing.T) {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
user := User{Balance: 1000}
db.Create(&user)
changed, err := HasFieldChanged(db, user.ID)
if err != nil {
t.Errorf("Error terjadi: %v", err)
}
if !changed {
t.Errorf("Expected true, got false")
}
}
Penjelasan Kode Unit Test
- Membuka koneksi database SQLite dan memastikan tabel
User
tersedia. - Menambahkan user dengan saldo awal 1000.
- Memanggil
HasFieldChanged
untuk mengecek apakah saldo berubah. - Mengecek apakah perubahan benar-benar terjadi.
6. Change Updating Values
Contoh Implementasi
// UpdateDynamicValue memperbarui nilai saldo berdasarkan parameter yang diberikan
func UpdateDynamicValue(db *gorm.DB, id uint, newBalance int) error {
return db.Model(&User{}).Where("id = ?", id).Update("balance", newBalance).Error
}
Penjelasan Kode
Update("balance", newBalance)
memperbarui saldo dengan nilai yang diberikan dari parameternewBalance
.
Unit Test
func TestUpdateDynamicValue(t *testing.T) {
db, _ := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
db.AutoMigrate(&User{})
user := User{Balance: 500}
db.Create(&user)
err := UpdateDynamicValue(db, user.ID, 2000)
if err != nil {
t.Errorf("Update gagal: %v", err)
}
var updatedUser User
db.First(&updatedUser, user.ID)
if updatedUser.Balance != 2000 {
t.Errorf("Expected balance 2000, got %d", updatedUser.Balance)
}
}
Penjelasan Kode Unit Test
- Membuka koneksi database SQLite dan memastikan tabel
User
tersedia. - Menambahkan user dengan saldo awal 500.
- Memanggil
UpdateDynamicValue
untuk memperbarui saldo menjadi 2000. - Mengecek apakah saldo yang diperbarui sesuai dengan ekspektasi.
Kesimpulan
Dalam artikel ini, kita telah membahas berbagai teknik advanced update di GORM, termasuk:
- Update with SQL Expression untuk melakukan operasi matematika dalam query.
- Update from SubQuery untuk memperbarui data berdasarkan hasil subquery.
- Without Hooks/Time Tracking untuk menghindari pemanggilan hooks atau perubahan timestamp otomatis.
- Returning Data From Modified Rows untuk mendapatkan data terbaru setelah update.
- Check Field has Changed? untuk mengecek apakah nilai field benar-benar berubah.
- Change Updating Values untuk memperbarui nilai secara dinamis sesuai dengan kondisi.
Dengan memahami teknik-teknik ini, Anda dapat mengoptimalkan proses pembaruan data di aplikasi berbasis Golang dengan GORM. Pastikan untuk selalu menguji setiap pembaruan dengan unit test agar fungsionalitas tetap terjaga.
12 Update Data Gorm Library Lanjutan (Bagian 1)
Artikel Terhangat
14 Menghapus (Delete) Data Gorm Library
03 Mar 2025
13 Advanced Update Data Gorm Library
03 Mar 2025
11 Update Data GORM Library
03 Mar 2025
08 Advanced Query dengan GORM di Golang
03 Mar 2025

14 Menghapus (Delete) Data Gorm Library

13 Advanced Update Data Gorm Library

11 Update Data GORM Library
