Pemrograman

05 Menampilkan Data atau Query Record di GORM dengan Golang

Pelajari cara menampilkan data atau query record di GORM menggunakan Golang. Panduan lengkap dengan contoh kode, unit test, dan berbagai metode query ke database.

GORM adalah library ORM yang populer di Golang yang mendukung berbagai database seperti MySQL, PostgreSQL, SQLite, dan SQL Server. Dalam artikel ini, kita akan membahas cara menampilkan data atau query record menggunakan GORM dengan berbagai metode yang tersedia.


1. Menampilkan Satu Objek

Untuk mendapatkan satu objek dari tabel database menggunakan GORM, kita dapat menggunakan metode First(), Take(), atau Last(). Metode ini digunakan untuk mengambil satu record saja sesuai urutan yang ditentukan.

Contoh Kode Fungsi

func GetFirstUser(db *gorm.DB) (*User, error) {
    var user User
    result := db.First(&user) // Mengambil satu record pertama dari tabel User
    return &user, result.Error // Mengembalikan data user dan error jika ada
}

Penjelasan Kode

  1. var user User → Mendeklarasikan variabel user sebagai struct User.
  2. result := db.First(&user) → Mengambil data pertama dari tabel User.
  3. return &user, result.Error → Mengembalikan user dan error jika ada.

Unit Test dengan SQLMock

func TestGetFirstUser(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 \"id\" LIMIT 1").
        WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "Alice"))
    
    user, err := GetFirstUser(gdb)
    assert.Nil(t, err)
    assert.Equal(t, "Alice", user.Name)
}

Penjelasan Unit Test

  1. Menggunakan SQLMock untuk membuat database mock.
  2. Membuat query yang diharapkan dieksekusi oleh GetFirstUser.
  3. Menambahkan hasil query dalam bentuk row.
  4. Memanggil GetFirstUser dan memastikan tidak ada error serta data yang diambil sesuai.

2. Menampilkan Objek dengan Primary Key

Jika kita ingin mengambil data berdasarkan primary key tertentu, kita bisa menggunakan metode First() dengan parameter ID.

Contoh Kode Fungsi

func GetUserByID(db *gorm.DB, id uint) (*User, error) {
    var user User
    result := db.First(&user, id) // Mengambil record dengan primary key tertentu
    return &user, result.Error // Mengembalikan data user dan error jika ada
}

Unit Test dengan SQLMock

func TestGetUserByID(t *testing.T) {
    db, mock, _ := sqlmock.New()
    gdb, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
    
    mock.ExpectQuery("SELECT \* FROM \"users\" WHERE \"id\" = \$1 ORDER BY \"id\" LIMIT 1").
        WithArgs(10).
        WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(10, "Bob"))
    
    user, err := GetUserByID(gdb, 10)
    assert.Nil(t, err)
    assert.Equal(t, uint(10), user.ID)
}

3. Mengambil Semua Data

Jika kita ingin mengambil semua data dari tabel, kita bisa menggunakan metode Find().

Contoh Kode Fungsi

func GetAllUsers(db *gorm.DB) ([]User, error) {
    var users []User
    result := db.Find(&users) // Mengambil semua data dari tabel User
    return users, result.Error // Mengembalikan daftar user dan error jika ada
}

Unit Test dengan SQLMock

func TestGetAllUsers(t *testing.T) {
    db, mock, _ := sqlmock.New()
    gdb, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
    
    mock.ExpectQuery("SELECT \* FROM \"users\"").
        WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).
            AddRow(1, "Alice").
            AddRow(2, "Bob"))
    
    users, err := GetAllUsers(gdb)
    assert.Nil(t, err)
    assert.Len(t, users, 2)
    assert.Equal(t, "Alice", users[0].Name)
    assert.Equal(t, "Bob", users[1].Name)
}

4. String Conditions

Menggunakan string conditions untuk mencari data berdasarkan kondisi tertentu dengan metode Where().

Contoh Kode Fungsi

func GetUserByName(db *gorm.DB, name string) (*User, error) {
    var user User
    result := db.Where("name = ?", name).First(&user)
    return &user, result.Error
}

Penjelasan Kode Fungsi

  1. var user User → Mendeklarasikan variabel user sebagai struct User.
  2. db.Where("name = ?", name).First(&user) → Mencari user berdasarkan field name.
  3. return &user, result.Error → Mengembalikan user yang ditemukan dan error jika ada.

Unit Test dengan SQLMock

func TestGetUserByName(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 ORDER BY \"id\" LIMIT 1").
        WithArgs("Alice").
        WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(1, "Alice"))
    
    user, err := GetUserByName(gdb, "Alice")
    assert.Nil(t, err)
    assert.Equal(t, "Alice", user.Name)
}

Penjelasan Kode Unit Test

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

5. Struct & Map Condition

Menggunakan struct atau map untuk mencari data dengan lebih fleksibel.

Contoh Kode Fungsi

func GetUsersByStruct(db *gorm.DB, condition User) ([]User, error) {
    var users []User
    result := db.Where(&condition).Find(&users)
    return users, result.Error
}

Penjelasan Kode Fungsi

  1. var users []User → Mendeklarasikan slice users sebagai tempat hasil query.
  2. db.Where(&condition).Find(&users) → Menggunakan struct condition sebagai filter untuk mencari user.
  3. return users, result.Error → Mengembalikan daftar user yang sesuai dengan kondisi.

Unit Test dengan SQLMock

func TestGetUsersByStruct(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 AND age = \$2").
        WithArgs("Bob", 30).
        WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age"}).AddRow(2, "Bob", 30))
    
    condition := User{Name: "Bob", Age: 30}
    users, err := GetUsersByStruct(gdb, condition)
    assert.Nil(t, err)
    assert.Len(t, users, 1)
    assert.Equal(t, "Bob", users[0].Name)
}

Penjelasan Kode Unit Test

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

6. Inline Condition

Menggunakan inline condition untuk mencari data langsung dengan parameter.

Contoh Kode Fungsi

func GetUserByInlineCondition(db *gorm.DB, field string, value interface{}) (*User, error) {
    var user User
    result := db.First(&user, field+" = ?", value)
    return &user, result.Error
}

Penjelasan Kode Fungsi

  1. var user User → Mendeklarasikan variabel user sebagai struct User.
  2. db.First(&user, field+" = ?", value) → Menyusun query berdasarkan field dan nilai yang diberikan.
  3. return &user, result.Error → Mengembalikan user yang ditemukan dan error jika ada.

Unit Test dengan SQLMock

func TestGetUserByInlineCondition(t *testing.T) {
    db, mock, _ := sqlmock.New()
    gdb, _ := gorm.Open(postgres.New(postgres.Config{Conn: db}), &gorm.Config{})
    
    mock.ExpectQuery("SELECT \* FROM \"users\" WHERE email = \$1 ORDER BY \"id\" LIMIT 1").
        WithArgs("alice@example.com").
        WillReturnRows(sqlmock.NewRows([]string{"id", "email"}).AddRow(3, "alice@example.com"))
    
    user, err := GetUserByInlineCondition(gdb, "email", "alice@example.com")
    assert.Nil(t, err)
    assert.Equal(t, "alice@example.com", user.Email)
}

Penjelasan Kode Unit Test

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

Lanjutan dari artikel ini mencakup berbagai metode query lainnya seperti Not Conditions, Selecting Specific Fields, Order, Limit & Offset, Group By & Having, Join, Join Preloading, Join a Derived Table, dan Scan, yang masing-masing akan disertai dengan fungsi dan unit test.

Untuk penjelasan lebih lanjut mengenai penggunaan database dalam Golang, silakan kunjungi:


comments powered by Disqus

Topik Terhangat

pemrograman
152
jaringan
28
tips-dan-trik
27
tutorial
20
hardware
11
linux
4
kubernetes
1
trik-and-tips
1