CodeBlanks Logo Icon CodeBlanks

Veritabanı katmanı

  • Go kursu
  • İleri seviye
  • Ders 44/68
  • 6 dk

database/sql ile veri erişim katmanını yazarsın.

Bellek içi repository

İlk aşamada veritabanı yerine bellekte çalışan bir repository yazmak, servisi hemen denemeni sağlar. HTTP sunucusu istekleri eşzamanlı işlediği için veri sync.Mutex ile korunur:

type memRepo struct {
    mu     sync.Mutex
    urunler []Urun
}

func (r *memRepo) Ekle(u Urun) error {
    r.mu.Lock()
    defer r.mu.Unlock()
    r.urunler = append(r.urunler, u)
    return nil
}

Veritabanına geçiş

Aynı Repo arayüzünü database/sql ile uygulayan ikinci bir tür yazınca servis kodu değişmez:

type sqlRepo struct{ db *sql.DB }

func (r sqlRepo) Ekle(u Urun) error {
    _, err := r.db.Exec("INSERT INTO urunler(ad, fiyat) VALUES(?, ?)", u.Ad, u.Fiyat)
    return err
}

main.go'da hangi uygulamanın kullanılacağı seçilir; buna bağımlılık enjeksiyonu denir.

Uygulama Bellek repository'si

Urun ve memRepo (sync.Mutex + []Urun) yaz. Ekle ve Liste yöntemleri kilitle çalışsın. İki ürün ekleyip len(r.Liste()) değerini yazdır.

Başlangıç kodu

main.go
package main

import (
    "fmt"
    "sync"
)

func main() {
    // buraya yaz
}

Örnek çözüm

main.go
package main

import (
    "fmt"
    "sync"
)

type Urun struct {
    Ad    string
    Fiyat float64
}

type memRepo struct {
    mu      sync.Mutex
    urunler []Urun
}

func (r *memRepo) Ekle(u Urun) error {
    r.mu.Lock()
    defer r.mu.Unlock()
    r.urunler = append(r.urunler, u)
    return nil
}

func (r *memRepo) Liste() []Urun {
    r.mu.Lock()
    defer r.mu.Unlock()
    return append([]Urun(nil), r.urunler...)
}

func main() {
    r := &memRepo{}
    r.Ekle(Urun{"Kalem", 10})
    r.Ekle(Urun{"Defter", 25})
    fmt.Println(len(r.Liste()))
}

Beklenen çıktı

2

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 memRepo yöntemleri neden işaretçi alıcı (<code>*memRepo</code>) kullanır?

  • JSON için
  • Mutex ve dilim kopyalanmasın, değişiklik aynı nesnede kalsın diye Doğru cevap
  • Daha kısa yazıldığı için
  • Arayüzler değer alıcıyı desteklemediği için

Açıklama: Değer alıcı her çağrıda kopya oluşturur; eklenen ürün kopyada kalır ve kopyalanan mutex koruma sağlamaz.

2 Kilidi bırak

Soru
r.mu.Lock()
____ r.mu.Unlock()
return append([]Urun(nil), r.urunler...)
Cevap
r.mu.Lock()
defer r.mu.Unlock()
return append([]Urun(nil), r.urunler...)

Açıklama: defer Unlock, fonksiyon nasıl biterse bitsin kilidin bırakılmasını garanti eder.

3 Repository uygulamaları

Kavram Anlamı
memRepo Bellekte, test için
sqlRepo database/sql ile
Repo Ortak arayüz
sync.Mutex Eşzamanlı erişimi korur

İleri seviye bölümündeki tüm dersler