1. ent Varlık İşlemlerine Giriş

Bu kılavuzda, ent çerçevesinde varlık işlemlerini ustalıkla öğrenmenizi sağlayacak, varlık oluşturma, sorgulama, güncelleme ve silme işlemlerinin tamamını kapsayan kapsamlı bir rehber bulacaksınız. Bu rehber, ent'in temel işlevselliğine adım adım dalmak isteyen acemiler için uygundur.

3. Varlık Oluşturma İşlemi

3.1 Tek Varlık Oluşturma

Bir varlık oluşturma, veri kalıcılığı için temel bir işlemdir. Aşağıda, ent çerçevesini kullanarak tek bir varlık nesnesi oluşturma ve veritabanına kaydetme adımları bulunmaktadır:

  1. İlk olarak, bir varlığın yapısını ve alanlarını tanımlayın, yani varlığın modelini şema dosyasında tanımlayın.
  2. Karşılık gelen varlık işlem kodunu oluşturmak için ent generate komutunu çalıştırın.
  3. Oluşturulan Create yöntemini kullanarak yeni bir varlık oluşturun ve zincirlenmiş çağrılar aracılığıyla varlığın alan değerlerini ayarlayın.
  4. Son olarak, varlığı veritabanına kaydetmek için Save yöntemini çağırın.

Aşağıdaki örnek, bir kullanıcı varlığı oluşturmayı ve kaydetmeyi göstermektedir:

package main

import (
    "context"
    "log"
    "entdemo/ent"
)

func main() {
    // Veritabanı etkileşimi için bir Client örneği oluşturun
    client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("Veritabanı bağlantısı açılamadı: %v", err)
    }
    defer client.Close()

    // Bir bağlam oluşturun
    ctx := context.Background()
    
    // Client kullanarak bir kullanıcı varlığı oluşturun
    a8m, err := client.User.
        Create().
        SetName("a8m").
        Save(ctx)
    if err != nil {
        log.Fatalf("Kullanıcı varlığı oluşturulamadı: %v", err)
    }

    // Varlık başarıyla veritabanına kaydedildi
    log.Printf("Kullanıcı varlığı kaydedildi: %v", a8m)
}

Bu örnekte, önce bir veritabanı istemcisi client oluşturulur. Daha sonra, User.Create yöntemi yeni kullanıcının özelliklerini ayarlamak için kullanılır ve nihayetinde kullanıcıyı veritabanına kaydetmek için Save yöntemi çağrılır.

3.2 Toplu Varlık Oluşturma

Belirli senaryolarda, veritabanı başlatması veya toplu veri içe aktarma işlemleri sırasında birden fazla varlık oluşturma ihtiyacı olabilir. ent çerçevesi, toplu şekilde varlık oluşturmayı sağlayan ve bireysel olarak oluşturup kaydetmekten daha iyi performans sunan bir yetenek sağlar.

Toplu varlık oluşturma adımları şunlardır:

  1. Create yöntemi yerine birden fazla varlık oluşturmayı sağlayan CreateBulk yöntemini kullanın.
  2. Oluşturulacak her varlık için Create yöntemini çağırın.
  3. Tüm varlıklar oluşturulduktan sonra, Save yöntemini kullanarak varlıkları toplu olarak veritabanına kaydedin.

Aşağıdaki örnek, toplu varlık oluşturmayı göstermektedir:

package main

import (
    "context"
    "log"
    "entdemo/ent"
)

func main() {
    client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("Veritabanı bağlantısı açılamadı: %v", err)
    }
    defer client.Close()
    ctx := context.Background()

    // Pet varlıklarını toplu şekilde oluşturun
    pets, err := client.Pet.CreateBulk(
        client.Pet.Create().SetName("pedro").SetOwner(a8m),
        client.Pet.Create().SetName("xabi").SetOwner(a8m),
        client.Pet.Create().SetName("layla").SetOwner(a8m),
    ).Save(ctx)
    if err != nil {
        log.Fatalf("Pet varlıkları toplu şekilde oluşturulamadı: %v", err)
    }

    log.Printf("Toplu olarak %d Pet varlığı oluşturuldu\n", len(pets))
}

Bu örnekte, önce bir client oluşturulur ve ardından CreateBulk yöntemi kullanılarak birden fazla Pet varlığı oluşturulur, adlarını ve sahip alanlarını ayarlar. Tüm varlıklar, Save yöntemi çağrıldığında veritabanına aynı anda kaydedilir, bu da büyük miktardaki verileri işlemek için daha iyi performans sağlar.

4. Varlık Sorgu İşlemleri

4.1 Temel Sorgulama

Veritabanı sorgulama, bilgi almanın temel yoludur. ent içinde bir sorgu başlatmak için Query yöntemi kullanılır. İşte temel varlık sorgulamanın adımları ve bir örneği:

  1. Kullanılabilir bir Client örneğiniz olduğundan emin olun.
  2. Sorgu oluşturmak için Client.Query() veya Pet.Query() gibi varlık yardımcı yöntemlerini kullanın.
  3. Gerekli olan filtreleme koşullarını ekleyin, örneğin Where.
  4. Sorguyu yürütün ve All yöntemini çağırarak sonuçları alın.
package main

import (
    "context"
    "log"
    "entdemo/ent"
    "entdemo/ent/user"
)

func main() {
    client, err := ent.Open("sqlite3", "file:ent?cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("Veritabanı bağlantısını açma başarısız oldu: %v", err)
    }
    defer client.Close()
    ctx := context.Background()

    // "a8m" adındaki tüm kullanıcıları sorgulayın
    users, err := client.User.
        Query().
        Where(user.NameEQ("a8m")).
        All(ctx)
    if err != nil {
        log.Fatalf("Kullanıcıları sorgulama başarısız oldu: %v", err)
    }

    for _, u := range users {
        log.Printf("Kullanıcı bulundu: %#v\n", u)
    }
}

Bu örnek, "a8m" adındaki tüm kullanıcıları bulmayı göstermektedir.

4.2 Sayfalama ve Sıralama

Sayfalama ve sıralama, sorgulama yaparken veri çıkış sırasını ve miktarını kontrol etmek için yaygın olarak kullanılan gelişmiş özelliklerdir. ent kullanarak sayfalama ve sıralama sorgularını nasıl gerçekleştireceğinizi aşağıda bulabilirsiniz:

  1. Limit yöntemini kullanarak döndürülecek maksimum sonuç sayısını belirleyin.
  2. Önceki sonuçların bazılarını atlamak için Offset yöntemini kullanın.
  3. Sıralama alanını ve yönünü belirtmek için Order yöntemini kullanın.

İşte sayfalama ve sıralama sorgusunun bir örneği:

package main

import (
    "context"
    "log"
    "entdemo/ent"
    "entdemo/ent/pet"
)

func main() {
    client, err := ent.Open("sqlite3", "file:ent?cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("Veritabanı bağlantısını açma başarısız oldu: %v", err)
    }
    defer client.Close()
    ctx := context.Background()

    // Yaşı azalan sırada evcil hayvanları sorgula ve sayfalama yap
    pets, err := client.Pet.
        Query().
        Order(ent.Desc(pet.FieldAge)).
        Limit(10).
        Offset(0).
        All(ctx)
    if err != nil {
        log.Fatalf("Evcil hayvanları sorgulama başarısız oldu: %v", err)
    }

    for _, p := range pets {
        log.Printf("Evcil hayvan bulundu: %#v\n", p)
    }
}

Bu örnek, yaşa göre azalan şekilde sıralanmış ilk sayfayı, en fazla 10 kaydı almayı göstermektedir. Limit ve Offset değerlerini değiştirerek, tüm veri seti üzerinden sayfa sayfa ilerleyebilirsiniz.

5. Varlık Güncelleme İşlemleri

5.1 Tek Bir Varlığı Güncelleme

Birçok uygulamada, varlıkların güncellenmesi günlük operasyonların temel bir parçasıdır. Bu bölümde, Ent çerçevesini kullanarak veritabanındaki tek bir varlığı nasıl güncelleyeceğimizi göstereceğiz.

Öncelikle, bir kullanıcının yaşını güncellememiz gerektiğini varsayarsak, Ent tarafından oluşturulan Update yöntemini kullanabiliriz.

// Varsayalım ki zaten 'a8m' adlı bir kullanıcı var ve bir bağlam 'ctx' var

a8m, err := a8m.Update().         // Bir kullanıcı güncelleme oluştur
    SetAge(30).                   // Kullanıcının yaşını 30'a ayarla
    Save(ctx)                     // Kaydetme işlemini gerçekleştirin ve sonucu döndürün
if err != nil {
    log.Fatalf("Kullanıcı güncelleme başarısız oldu: %v", err)
}

Aynı anda birden fazla alanı da güncelleyebilirsiniz:

a8m, err := a8m.Update().
    SetAge(30).                    // Yaşı güncelle
    SetName("Ariel").              // İsmi güncelle
    AddRank(10).                   // Sırayı 10 arttır
    Save(ctx)
if err != nil {
    log.Fatalf("Kullanıcı güncelleme başarısız oldu: %v", err)
}

Güncelleme işlemi zincirlenebilir, bu da çok esnek ve okunması kolay bir yapıdır. Save yöntemini çağırarak güncellemeyi gerçekleştirebilir ve güncellenmiş varlığı veya hata mesajını alabilirsiniz.

5.2 Koşullu Güncellemeler

Ent, koşullara dayalı güncellemeleri gerçekleştirmenizi sağlar. İşte yalnızca belirli koşulları karşılayan kullanıcıların güncelleneceği bir örnek.

// Varsayalım ki bir kullanıcının `id`'si var ve bu kullanıcıyı mevcut `currentVersion` sürümü için tamamlanmış olarak işaretlemek istiyoruz

err := client.Todo.
    UpdateOneID(id).          // Kullanıcı kimliğine göre güncelleme oluştur
    SetStatus(todo.StatusDone).
    AddVersion(1).
    Where(
        todo.Version(currentVersion),  // Güncelleme işlemi yalnızca mevcut sürüm eşleştiğinde gerçekleştirilir
    ).
    Exec(ctx)
switch {
case ent.IsNotFound(err):
    fmt.Println("Görev bulunamadı")
case err != nil:
    fmt.Println("Güncelleme hatası:", err)
}

Koşullu güncellemeler kullanılırken .Where() yönteminin dahil edilmesi gereklidir. Bu, veri tabanındaki mevcut değerlere dayalı olarak güncellemenin yapılıp yapılmayacağını belirlemenizi sağlar; bu da veri bütünlüğünü ve tutarlılığını sağlamak için kritiktir.

6. Varlık Silme İşlemleri

6.1 Tek Bir Varlığın Silinmesi

Varlıkların silinmesi, veritabanı işlemlerinde önemli bir fonksiyondur. Ent çerçevesi, silme işlemlerini gerçekleştirmek için basit bir API sağlar.

Aşağıdaki örnek, belirli bir kullanıcı varlığını nasıl sileceğimizi göstermektedir:

err := client.User.
    DeleteOne(a8m).  // Bir kullanıcı silme oluştur
    Exec(ctx)        // Silme işlemini gerçekleştir
if err != nil {
    log.Fatalf("Kullanıcı silinemedi: %v", err)
}

6.2 Koşullu Silme

Güncelleme işlemlerine benzer şekilde, belirli koşullara dayalı olarak silme işlemleri de gerçekleştirebiliriz. Bazı senaryolarda, yalnızca belirli koşulları karşılayan varlıkları silmek isteyebiliriz. .Where() yöntemini kullanarak bu koşulları tanımlayabiliriz:

// Diyelim ki belirli bir tarihten önce güncellenmiş tüm dosyaları silmek istiyoruz

affected, err := client.File.
    Delete().
    Where(file.UpdatedAtLT(date)).  // Dosyanın güncelleme zamanı verilen tarihten önceyse yalnızca silme işlemi gerçekleştir
    Exec(ctx)
if err != nil {
    log.Fatalf("Dosyalar silinemedi: %v", err)
}

// Bu işlem, silme işlemi tarafından etkilenen kayıt sayısını döndürür
fmt.Printf("%d dosya silindi\n", affected)

Koşullu silme işlemleri kullanarak veri işlemlerimiz üzerinde kesin kontrol sağlarız; bu da yalnızca koşulları tam olarak karşılayan varlıkların silindiğinden emin olur. Bu, veritabanı işlemlerinin güvenilirliğini ve güvenliğini artırır.