Skip to content
Santekno.com | Level Up Your Engineering Skills
ID
📖 0%
23 Jan 2024 · 5 mnt baca ·Artikel 82 / 119
Go

05 Membuat Repository Sebagai Data Akses

IH
Ihsan Arif
Penulis di Santekno · Backend Engineer

Pada kali ini kita akan membuat Article Repository yang kebutuhannya untuk komunikasi ke dalam database MySQL. Kita memiliki tabel pada MySQL pada sebelumnya sudah kita jelaskan, lalu kita akan membuat fungsi-fungsi yang nantinya akan digunakan untuk kebutuhan spesifikasi API. Berikut ini fungsi yang akan kita seperti ini

  1. Fungsi Save() digunakan untuk menyimpan data article ke dalam tabel pada database
  2. Fungsi Update() digunakan untuk mengubah data article
  3. Fungsi Delete() digunakan untuk menghapus data article
  4. Fungsi FindById() digunakan untuk mencari data berdasarkan Id
  5. Fungsi GetAll() digunakan untuk mengambil data keseluruhan dari tabel pada database

Fungsi-fungsi tersebut kita simpan dalam satu file article_repository.go dengan menggunakan type interface sebagai kontrak yang nantinya kita implementasikan ditiap masing-masing fungsi.

Pertama buat file article_repository.go pada folder repository lalu isi file tersebut dengan kode dibawah ini.

go
 1package repository
 2
 3import (
 4	"context"
 5
 6	"github.com/santekno/learn-golang-restful/models"
 7)
 8
 9type ArticleRepository interface {
10	GetAll(ctx context.Context) ([]*models.Article, error)
11	GetByID(ctx context.Context, id int64) (*models.Article, error)
12	Update(ctx context.Context, article *models.Article) (*models.Article, error)
13	Store(ctx context.Context, article *models.Article) (int64, error)
14	Delete(ctx context.Context, id int64) (bool, error)
15}

Interface ini akan menjadi atribute utama dan yang akan diinject pada usecase layer. Usecase nantinya hanya mengetahui fungsi di repository melalui interface ini, sehingga repository harus implement interface ini.

Selanjutnya kita akan membuat satu persatu fungsi yang sudah kita definisikan ini menjadi fungsi implementasi yang akan kita pisah file-nya.

Buat file pada folder repository mysql/article.go lalu isi inisialisasi kode seperti ini

go
1type ArticleStore struct {
2	db *sql.DB
3}
4
5// New will create an object that represent the article_repository interface
6func New(conn *sql.DB) *ArticleStore {
7	return &ArticleStore{conn}
8}

Struct diatas kita butuhkan untuk mengirimkan koneksi database yang akan kita gunakan untuk melakukan pengolahan data misalkan mengambil, menambah, mengubah dan menghapus data article di dalam table pada database. Inisialisasi struct tersebut akan dipanggil oleh setiap fungsi untuk kebutuhan pengolahan.

Membuat Fungsi Ambil Semua Data Article

Berikut ini fungsi untuk mengambil data article secara keseluruhan seperti dibawah ini.

go
 1func (r *ArticleStore) GetAll(ctx context.Context) ([]*models.Article, error) {
 2	var result []*models.Article
 3
 4	rows, err := r.db.QueryContext(ctx, queryGetAll)
 5	if err != nil {
 6		return result, err
 7	}
 8
 9	defer rows.Close()
10
11	for rows.Next() {
12		t := models.Article{}
13		err = rows.Scan(&t.ID, &t.Title, &t.Content, &t.CreateAt, &t.UpdateAt)
14
15		if err != nil {
16			return nil, err
17		}
18
19		result = append(result, &t)
20	}
21
22	return result, nil
23}
Fungsi ini membutuhkan query mengambil data ke dalam database, pada kode diatas memanggil variabel queryGetAll yang berisi query seperti ini.
go
1const queryGetAll = `SELECT id, title, content, create_at, update_at FROM articles`

Pada fungsi ini kita memanggil QueryContext yang mana fungsi tersebut merupakan library dari database/sql yang bisa kita gunakan untuk melakukan pengambilan data berdasarkan query yang sudah di definisikan.

Membuat Fungsi Mengambil Data berdasarkan Id Article

Fungsi untuk mengambil data berdasarkan Id bisa kita lihat seperti ini.

go
 1func (r *ArticleStore) GetByID(ctx context.Context, id int64) (*models.Article, error) {
 2	var result models.Article
 3
 4	err := r.db.QueryRowContext(ctx, queryGetById, id).Scan(&result.ID, &result.Title, &result.Content, &result.CreateAt, &result.UpdateAt)
 5	if err != nil {
 6		return &result, err
 7	}
 8
 9	return &result, nil
10}

Dengan query yang digunakan queryGetById seperti ini.

go
1const queryGetById = `SELECT id, title, content, create_at, update_at FROM articles WHERE id=?`

Pada query berdasarkan Id ini kita menggunakan fungsi QueryRowContext pada libary database/sql yang mana perbedaannya dari QueryContext yaitu hasil dari pengembalian datanya, jika kita menggunakan QueryContext maka data yang dihasilkan akan berupa rows yang lebih dari satu sehingga perlu kita lakukan perulangan karena banyaknya data yang dikembalikan. Sedangkan untuk QueryRowContext data yang dikembalikan hanya satu data saja yang mana bisa lngsung kita input di dalam struct article.

Membuat Fungsi Mengubah Data Article

Fungsi mengubah data untuk article ini bisa dilihat seperti ini.

go
 1func (r *ArticleStore) Update(ctx context.Context, article *models.Article) (*models.Article, error) {
 2	res, err := r.db.ExecContext(ctx, queryUpdate, article.Title, article.Content, article.UpdateAt, article.ID)
 3	if err != nil {
 4		return nil, err
 5	}
 6
 7	count, err := res.RowsAffected()
 8	if err != nil {
 9		return nil, err
10	}
11
12	fmt.Printf("success update with affected %d", count)
13	return article, nil
14}

Dengan menggunakan query UPDATE sql kita bisa mengubah beberapa kolom yang ada didatabase dengan parameter Id tertentu.

go
1const queryUpdate = `UPDATE article SET nim=?, name=?, birth_place=? WHERE id=?`

Membuat Fungsi Hapus Data Article

Berikut fungsi hapus data article seperti ini.

go
 1func (r *ArticleStore) Store(ctx context.Context, article *models.Article) (int64, error) {
 2	res, err := r.db.ExecContext(ctx, queryInsert, article.Title, article.Content, article.CreateAt, article.UpdateAt)
 3	if err != nil {
 4		return 0, err
 5	}
 6
 7	lastId, err := res.LastInsertId()
 8	if err != nil {
 9		return 0, err
10	}
11
12	fmt.Printf("success create with lastId: %d", lastId)
13	return lastId, nil
14}
15
16func (r *ArticleStore) Delete(ctx context.Context, id int64) (bool, error) {
17	_, err := r.db.ExecContext(ctx, queryDelete, id)
18	if err != nil {
19		return false, err
20	}
21
22	return true, nil
23}

Dengan query DELETE sql kita bisa menghapus data dalam tabel

go
1const queryDelete = `DELETE FROM article WHERE id=?`

Membuat Fungsi Menambah Data Article

Fungsi untuk menambahkan data article bisa kita buat seperti ini.

go
 1func (r *ArticleStore) Store(ctx context.Context, article *models.Article) (int64, error) {
 2	res, err := r.db.ExecContext(ctx, queryInsert, article.Title, article.Content, article.CreateAt)
 3	if err != nil {
 4		return 0, err
 5	}
 6
 7	lastId, err := res.LastInsertId()
 8	if err != nil {
 9		return 0, err
10	}
11
12	fmt.Printf("success create with lastId: %d", lastId)
13	return lastId, nil
14}

Dengan menggunakan query INSERT kita bisa menambahkan data ke dalam tabel article.

go
1const queryInsert = `INSERT INTO articles(title, content, create_at, update_at) VALUES(?,?,?,?)`

Jika kita lihat untuk menambahkan, mengubah dan menghapus data fungsi pada library database/sql yang digunakan adalah ExecContext. Fungsi ini kita gunakan ketika ada kebutuhan berupa DML atau ketika ada perubahan data.

Artikel Terkait

💬 Komentar