Pemrograman

07 Query Data Gorm Library Lanjutan (Bagian 1)

Pelajari berbagai metode query lanjutan di GORM dengan Golang, termasuk Not Conditions, Selecting Fields, Order, Limit, Offset, dan lainnya. Dilengkapi contoh kode dan unit test.

Setelah membahas dasar-dasar query di GORM pada artikel sebelumnya, kali ini kita akan mendalami beberapa metode query lanjutan yang sering digunakan untuk mengelola data dengan lebih fleksibel. Setiap metode akan dilengkapi dengan fungsi dan unit test agar mudah dipahami dan diterapkan.


7. Not Conditions

Metode Not() digunakan untuk mengambil data yang tidak memenuhi kondisi tertentu. Contohnya, kita bisa mengambil semua user yang namanya bukan “John”.

Contoh Kode Fungsi

func GetUsersNotNamed(db *gorm.DB, name string) ([]User, error) {
    var users []User
    result := db.Where("name <> ?", name).Find(&users)
    return users, result.Error
}

Penjelasan Kode Fungsi

  1. var users []User → Mendeklarasikan slice untuk menampung hasil query.
  2. db.Where("name <> ?", name).Find(&users) → Mengambil semua user yang namanya bukan name.
  3. return users, result.Error → Mengembalikan hasil query dan error jika ada.

Unit Test dengan SQLMock

func TestGetUsersNotNamed(t *testing.T) {
    db, mock, _ := sqlmock.New()
    gdb, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
    
    mock.ExpectQuery("SELECT \* FROM \"users\" WHERE name <> \$1").
        WithArgs("John").
        WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "Alice").AddRow(2, "Bob"))
    
    users, err := GetUsersNotNamed(gdb, "John")
    assert.Nil(t, err)
    for _, user := range users {
        assert.NotEqual(t, "John", user.Name)
    }
}

Penjelasan Kode Unit Test

  1. Membuat database mock menggunakan SQLMock.
  2. Menentukan query yang diharapkan dijalankan oleh fungsi GetUsersNotNamed.
  3. Memasukkan data hasil query yang akan dikembalikan.
  4. Memanggil fungsi GetUsersNotNamed dan memverifikasi bahwa hasilnya sesuai.

8. Selecting Specific Fields

Metode Select() digunakan untuk memilih field tertentu dalam query agar lebih efisien.

Contoh Kode Fungsi

func GetUserNames(db *gorm.DB) ([]string, error) {
    var names []string
    result := db.Model(&User{}).Select("name").Pluck("name", &names)
    return names, result.Error
}

Penjelasan Kode Fungsi

  1. db.Model(&User{}) → Menentukan tabel yang digunakan dalam query.
  2. .Select("name").Pluck("name", &names) → Mengambil hanya field name dan menyimpannya dalam slice names.
  3. return names, result.Error → Mengembalikan daftar nama dan error jika ada.

Unit Test dengan SQLMock

func TestGetUserNames(t *testing.T) {
    db, mock, _ := sqlmock.New()
    gdb, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
    
    mock.ExpectQuery("SELECT name FROM \"users\"").
        WillReturnRows(sqlmock.NewRows([]string{"name"}).AddRow("Alice").AddRow("Bob"))
    
    names, err := GetUserNames(gdb)
    assert.Nil(t, err)
    assert.Greater(t, len(names), 0)
}

Penjelasan Kode Unit Test

  1. Membuat database mock menggunakan SQLMock.
  2. Menentukan query yang diharapkan dijalankan oleh fungsi GetUserNames.
  3. Memasukkan data hasil query yang akan dikembalikan.
  4. Memanggil fungsi GetUserNames dan memverifikasi bahwa hasilnya sesuai.

9. Order

Metode Order() digunakan untuk mengurutkan hasil query berdasarkan field tertentu.

Contoh Kode Fungsi

func GetUsersOrderedByAge(db *gorm.DB) ([]User, error) {
    var users []User
    result := db.Order("age desc").Find(&users)
    return users, result.Error
}

Penjelasan Kode Fungsi

  1. db.Order("age desc").Find(&users) → Mengambil user dan mengurutkannya berdasarkan age dari yang terbesar.
  2. return users, result.Error → Mengembalikan hasil query dan error jika ada.

Unit Test dengan SQLMock

func TestGetUsersOrderedByAge(t *testing.T) {
    db, mock, _ := sqlmock.New()
    gdb, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
    
    mock.ExpectQuery("SELECT \* FROM \"users\" ORDER BY age desc").
        WillReturnRows(sqlmock.NewRows([]string{"id", "age"}).AddRow(1, 40).AddRow(2, 30))
    
    users, err := GetUsersOrderedByAge(gdb)
    assert.Nil(t, err)
    assert.GreaterOrEqual(t, users[0].Age, users[len(users)-1].Age)
}

Penjelasan Kode Unit Test

  1. Membuat database mock menggunakan SQLMock.
  2. Menentukan query yang diharapkan dijalankan oleh fungsi GetUsersOrderedByAge.
  3. Memasukkan data hasil query yang akan dikembalikan.
  4. Memanggil fungsi GetUsersOrderedByAge dan memverifikasi bahwa hasilnya sesuai.

Dengan menggunakan SQLMock, kita dapat menguji kode tanpa harus benar-benar terhubung ke database. Ini memastikan bahwa fungsi bekerja seperti yang diharapkan dan hasil query dapat diverifikasi dengan lebih baik.

10. Limit & Offset

Metode Limit() dan Offset() digunakan untuk membatasi jumlah hasil query dan menentukan dari mana data diambil.

Contoh Kode Fungsi

func GetLimitedUsers(db *gorm.DB, limit int, offset int) ([]User, error) {
    var users []User
    result := db.Limit(limit).Offset(offset).Find(&users)
    return users, result.Error
}

Penjelasan Kode Fungsi

  1. db.Limit(limit).Offset(offset).Find(&users) → Mengambil limit data dimulai dari offset tertentu.
  2. return users, result.Error → Mengembalikan hasil query dan error jika ada.

Unit Test dengan SQLMock

func TestGetLimitedUsers(t *testing.T) {
    db, mock, _ := sqlmock.New()
    gdb, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
    
    mock.ExpectQuery("SELECT \* FROM \"users\" LIMIT \$1 OFFSET \$2").
        WithArgs(5, 0).
        WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "Alice").AddRow(2, "Bob"))
    
    users, err := GetLimitedUsers(gdb, 5, 0)
    assert.Nil(t, err)
    assert.LessOrEqual(t, len(users), 5)
}

Penjelasan Kode Unit Test

  1. Membuat database mock menggunakan SQLMock.
  2. Menentukan query yang diharapkan dijalankan oleh fungsi GetLimitedUsers.
  3. Memasukkan data hasil query yang akan dikembalikan.
  4. Memanggil fungsi GetLimitedUsers dan memverifikasi bahwa hasilnya sesuai.

Selanjutnya, kita akan membahas Group By & Having, Join, Join Preloading, Join a Derived Table, dan Scan, dengan contoh kode dan unit test yang lengkap.

Untuk penjelasan lebih lanjut mengenai database dalam Golang, kunjungi:


comments powered by Disqus