Skip to content
Santekno.com | Level Up Your Engineering Skills
ID
📖 0%
Go

10 Advance Query Data Gorm Library (Bagian 2)

· 6 mnt baca ·Ihsan Arif

Pelajari teknik query lanjutan di GORM dengan Golang, termasuk Find To Map, FirstOrInit, Query Hooks, Iteration, dan lainnya, lengkap dengan contoh kode dan unit test.

Artikel ini merupakan lanjutan dari pembahasan sebelumnya tentang Advanced Query dengan GORM. Kali ini, kita akan membahas berbagai teknik lanjutan lainnya seperti FindInBatches, Query Hooks, Pluck, Scopes, dan Count, lengkap dengan contoh kode dan unit test.


13. FindInBatches

Metode FindInBatches digunakan untuk menangani dataset dalam jumlah besar dengan membagi proses pengambilan data menjadi batch kecil untuk menghindari penggunaan memori yang berlebihan.

Fungsi

go
1func BatchProcessUsers(db *gorm.DB) error {
2    batchSize := 100 // Menentukan ukuran batch
3    return db.Model(&User{}).FindInBatches(&[]User{}, batchSize, func(tx *gorm.DB, batch []User) error {
4        return nil // Menjalankan operasi pada setiap batch
5    }).Error
6}

Penjelasan Kode

  1. batchSize := 100 → Menentukan jumlah record yang diambil dalam satu batch.
  2. db.Model(&User{}) → Menentukan model yang digunakan dalam query.
  3. .FindInBatches(&[]User{}, batchSize, func(tx *gorm.DB, batch []User) error { ... }) → Mengambil data dalam batch kecil dan menerapkan operasi pada setiap batch.
  4. return nil → Tidak melakukan operasi tambahan pada batch.
  5. return db.FindInBatches(...).Error → Mengembalikan error jika ada masalah saat proses batch berlangsung.

Unit Test

go
 1func TestBatchProcessUsers_Success(t *testing.T) {
 2    err := BatchProcessUsers(db)
 3    assert.Nil(t, err) // Memastikan tidak ada error saat proses batch berhasil
 4}
 5
 6func TestBatchProcessUsers_Error(t *testing.T) {
 7    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
 8    err := BatchProcessUsers(db)
 9    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
10}

Penjelasan Unit Test

  1. Memanggil BatchProcessUsers(db) untuk menguji eksekusi batch.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Menguji skenario error dengan database tanpa tabel User untuk memastikan error terjadi.

14. Query Hooks

Metode Query Hooks digunakan untuk memproses data sebelum atau setelah eksekusi query, misalnya untuk memformat data sebelum disimpan ke database.

Fungsi

go
1type User struct {
2    gorm.Model
3    Name string
4}
5
6func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
7    u.Name = strings.ToUpper(u.Name) // Mengubah nama menjadi huruf besar sebelum disimpan
8    return
9}

Penjelasan Kode

  1. type User struct { ... } → Mendefinisikan model User.
  2. BeforeCreate(tx *gorm.DB) → Hook yang akan dijalankan sebelum record dibuat.
  3. u.Name = strings.ToUpper(u.Name) → Mengubah nama user menjadi huruf kapital sebelum disimpan ke database.

Unit Test

go
 1func TestQueryHook_Success(t *testing.T) {
 2    user := User{Name: "charlie"}
 3    db.Create(&user)
 4    assert.Equal(t, "CHARLIE", user.Name) // Memastikan nama telah dikonversi ke huruf besar
 5}
 6
 7func TestQueryHook_Error(t *testing.T) {
 8    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
 9    user := User{Name: "charlie"}
10    err := db.Create(&user).Error
11    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
12}

Penjelasan Unit Test

  1. Membuat user dengan nama “charlie”.
  2. Menyimpan user ke database dan memastikan bahwa nama telah dikonversi menjadi “CHARLIE”.
  3. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

15. Pluck

Metode Pluck digunakan untuk mengambil nilai dari satu kolom tertentu dan menyimpannya dalam slice.

Fungsi

go
1func GetUserNames(db *gorm.DB) ([]string, error) {
2    var names []string // Slice untuk menyimpan hasil query
3    result := db.Model(&User{}).Pluck("name", &names)
4    return names, result.Error // Mengembalikan daftar nama dan error jika ada
5}

Penjelasan Kode

  1. var names []string → Deklarasi slice untuk menyimpan hasil query.
  2. db.Model(&User{}) → Menentukan model yang digunakan.
  3. .Pluck("name", &names) → Mengambil nilai dari kolom name dan menyimpannya dalam slice names.

Unit Test

go
 1func TestGetUserNames_Success(t *testing.T) {
 2    names, err := GetUserNames(db)
 3    assert.Nil(t, err) // Memastikan tidak ada error
 4    assert.Greater(t, len(names), 0) // Memastikan hasil query tidak kosong
 5}
 6
 7func TestGetUserNames_Error(t *testing.T) {
 8    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
 9    names, err := GetUserNames(db)
10    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
11}

Penjelasan Unit Test

  1. Memanggil GetUserNames(db) untuk mengambil daftar nama.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

16. Scopes

Metode Scopes digunakan untuk mendefinisikan query yang dapat digunakan kembali, sehingga query lebih bersih dan mudah dibaca.

Fungsi

go
1func ActiveUsers(db *gorm.DB) *gorm.DB {
2    return db.Where("active = ?", true) // Filter hanya user yang aktif
3}
4
5func GetActiveUsers(db *gorm.DB) ([]User, error) {
6    var users []User
7    result := db.Scopes(ActiveUsers).Find(&users) // Menggunakan scope yang telah didefinisikan
8    return users, result.Error
9}

Penjelasan Kode

  1. func ActiveUsers(db *gorm.DB) *gorm.DB → Mendefinisikan fungsi scope yang mengembalikan query hanya untuk user yang aktif.
  2. db.Where("active = ?", true) → Filter hanya user yang memiliki atribut active = true.
  3. func GetActiveUsers(db *gorm.DB) ([]User, error) → Fungsi untuk mengambil daftar user yang aktif dengan menggunakan scope ActiveUsers.
  4. db.Scopes(ActiveUsers).Find(&users) → Menerapkan scope ActiveUsers untuk mendapatkan daftar user yang aktif.

Unit Test

go
 1func TestGetActiveUsers_Success(t *testing.T) {
 2    users, err := GetActiveUsers(db)
 3    assert.Nil(t, err) // Memastikan tidak ada error
 4    assert.Greater(t, len(users), 0) // Memastikan ada user aktif
 5}
 6
 7func TestGetActiveUsers_Error(t *testing.T) {
 8    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
 9    users, err := GetActiveUsers(db)
10    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
11}

Penjelasan Unit Test

  1. Memanggil GetActiveUsers(db) untuk mengambil daftar user yang aktif.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Memeriksa jumlah user aktif lebih dari nol menggunakan assert.Greater(t, len(users), 0).
  4. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

(Tambahkan kode, penjelasan, dan unit test di sini)


17. Count

Metode Count digunakan untuk menghitung jumlah record dalam suatu tabel.

Fungsi

go
1func CountUsers(db *gorm.DB) (int64, error) {
2    var count int64 // Variabel untuk menyimpan hasil hitungan
3    result := db.Model(&User{}).Count(&count)
4    return count, result.Error // Mengembalikan jumlah user dan error jika ada
5}

Penjelasan Kode

  1. var count int64 → Deklarasi variabel count untuk menyimpan jumlah record yang dihitung.
  2. db.Model(&User{}) → Menentukan model yang digunakan untuk query count.
  3. .Count(&count) → Menghitung jumlah record dalam tabel users dan menyimpannya dalam variabel count.
  4. return count, result.Error → Mengembalikan jumlah user dan error jika ada.

Unit Test

go
 1func TestCountUsers_Success(t *testing.T) {
 2    count, err := CountUsers(db)
 3    assert.Nil(t, err) // Memastikan tidak ada error
 4    assert.Greater(t, count, int64(0)) // Memastikan jumlah user lebih dari 0
 5}
 6
 7func TestCountUsers_Error(t *testing.T) {
 8    db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) // Membuka database kosong
 9    count, err := CountUsers(db)
10    assert.NotNil(t, err) // Memastikan error terjadi karena tabel tidak tersedia
11}

Penjelasan Unit Test

  1. Memanggil CountUsers(db) untuk menghitung jumlah user dalam database.
  2. Memastikan tidak ada error dengan assert.Nil(t, err) pada skenario sukses.
  3. Memeriksa jumlah user lebih dari nol menggunakan assert.Greater(t, count, int64(0)).
  4. Menguji skenario error dengan database kosong untuk memastikan error terjadi.

Untuk informasi lebih lanjut, kunjungi:


IH
Ihsan Arif
Backend engineer & penulis di Santekno. Aktif menulis tentang Go, Laravel, dan arsitektur backend modern.
Follow

💬 Komentar