emirhanHCL 1
emirhanHCL
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
farkmt2official 1
farkmt2official
Hikaye Ekle

[NODE JS] Prisma ile CRUD İşlemleri

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] Prisma ile CRUD İşlemleri​


Prisma ile CRUD işlemleri yapmak, geleneksel ORM'lere kıyasla çok daha sezgisel ve güvenli. Prisma Client, şema dosyanızdan otomatik olarak üretildiği için tüm modeller, alanlar ve ilişkiler hakkında tam tip bilgisine sahiptir. Bu sayede sorgu yazarken IDE'niz size hangi alanları kullanabileceğinizi, hangi filtreleri uygulayabileceğinizi ve hangi ilişkileri yükleyebileceğinizi gösterir. Yanlış bir alan adı yazdığınızda derleme zamanında hata alırsınız — çalışma zamanına kadar beklemenize gerek kalmaz.

Create işlemleri Prisma'da çok zengin. Tek kayıt oluşturmak için create, birden fazla kayıt için createMany kullanılır. İlişkili verileri aynı anda oluşturabilirsiniz: iç içe create ile yeni ilişkili kayıtlar, connect ile mevcut kayıtlara bağlantı, connectOrCreate ile varsa bağlan yoksa oluştur mantığı kullanılabilir. Bu iç içe yazma özelliği kodunuzu çok temiz tutar.

Read işlemlerinde Prisma'nın gücü iyice ortaya çıkar. findUnique benzersiz alanlarla tek kayıt, findFirst ilk eşleşen kayıt, findMany birden fazla kayıt getirir. select ile sadece istediğiniz alanları seçebilir, include ile ilişkili verileri yükleyebilirsiniz. Filtreleme için where objesi içinde equals, not, in, notIn, contains, startsWith, endsWith, gt, gte, lt, lte gibi operatörler kullanılır.

Update işlemlerinde update tek kayıt, updateMany birden fazla kayıt günceller. upsert ise kayıt varsa güncelle, yoksa oluştur mantığıyla çalışır. İlişkili verileri güncellerken set, disconnect, connect, create, update, upsert, delete gibi iç içe işlemler yapılabilir.

Delete işlemleri delete ve deleteMany ile yapılır. Cascade silme şemada tanımlandığı şekilde otomatik olarak uygulanır. Yumuşak silme (soft delete) için genellikle bir "silindiTarihi" alanı kullanılır ve Prisma middleware'leri ile bu mantık otomatikleştirilebilir.

Transaction desteği de Prisma'da çok güçlü. prisma.$transaction metodu ile birden fazla işlemi atomik olarak çalıştırabilirsiniz. İnteraktif transaction'lar, ardışık transaction'lar ve iç içe yazma işlemleri desteklenir. Bu özellik veri bütünlüğü için kritik öneme sahiptir.

Sayfalama için Prisma, cursor-based ve offset-based olmak üzere iki yöntem sunar. take ve skip ile offset tabanlı, cursor ile imleç tabanlı sayfalama yapılabilir. Büyük veri setlerinde imleç tabanlı sayfalama daha performanslıdır.

JavaScript:
// Prisma ile Kapsamlı CRUD İşlemleri
const { PrismaClient } = require('@prisma/client');

const prisma = new PrismaClient({
  log: ['query']
});

// =============================================
// CREATE İşlemleri
// =============================================
async function olusturmaIslemleri() {
  console.log('=== CREATE İşlemleri ===
');

  // 1. Basit kayıt oluşturma
  const urun = await prisma.urun.create({
    data: {
      ad: 'Kablosuz Kulaklık',
      aciklama: 'Bluetooth 5.0 destekli profesyonel kulaklık',
      fiyat: 449.99,
      stok: 100,
      sku: 'KLK-001',
      aktif: true
    }
  });
  console.log('Ürün oluşturuldu:', urun.ad);

  // 2. İlişkili verilerle birlikte oluşturma
  const kategoriVeUrunler = await prisma.kategori.create({
    data: {
      ad: 'Elektronik',
      slug: 'elektronik',
      aciklama: 'Elektronik ürünler ve aksesuarlar',
      urunler: {
        create: [
          {
            ad: 'Akıllı Saat',
            aciklama: 'Sağlık takip özellikli akıllı saat',
            fiyat: 1299.99,
            stok: 50,
            sku: 'SAT-001'
          },
          {
            ad: 'Tablet',
            aciklama: '10 inç ekranlı tablet bilgisayar',
            fiyat: 3499.99,
            stok: 30,
            sku: 'TAB-001'
          }
        ]
      }
    },
    include: {
      urunler: true
    }
  });
  console.log('Kategori ve ürünler oluşturuldu:', kategoriVeUrunler.ad);
  console.log('Ürün sayısı:', kategoriVeUrunler.urunler.length);

  // 3. connectOrCreate ile akıllı oluşturma
  const gonderi = await prisma.gonderi.create({
    data: {
      baslik: 'Prisma ile Veritabanı Yönetimi',
      slug: 'prisma-veritabani-yonetimi',
      icerik: 'Prisma ORM kullanarak etkili veritabanı yönetimi...',
      durum: 'YAYINDA',
      yazar: {
        connectOrCreate: {
          where: { email: 'yazar@ornek.com' },
          create: {
            ad: 'Deniz',
            soyad: 'Akın',
            email: 'yazar@ornek.com',
            sifre: 'guvenliSifre123'
          }
        }
      },
      etiketler: {
        create: [
          {
            etiket: {
              connectOrCreate: {
                where: { slug: 'prisma' },
                create: { ad: 'Prisma', slug: 'prisma' }
              }
            }
          },
          {
            etiket: {
              connectOrCreate: {
                where: { slug: 'nodejs' },
                create: { ad: 'Node.js', slug: 'nodejs' }
              }
            }
          }
        ]
      }
    },
    include: {
      yazar: true,
      etiketler: { include: { etiket: true } }
    }
  });
  console.log('Gönderi oluşturuldu:', gonderi.baslik);

  // 4. Toplu oluşturma
  const topluSonuc = await prisma.musteri.createMany({
    data: [
      { ad: 'Ahmet', soyad: 'Yılmaz', email: 'ahmet@ornek.com', telefon: '5551112233' },
      { ad: 'Fatma', soyad: 'Demir', email: 'fatma@ornek.com', telefon: '5554445566' },
      { ad: 'Mehmet', soyad: 'Öztürk', email: 'mehmet@ornek.com', telefon: '5557778899' },
      { ad: 'Ayşe', soyad: 'Çelik', email: 'ayse@ornek.com', telefon: '5550001122' }
    ],
    skipDuplicates: true
  });
  console.log(`${topluSonuc.count} müşteri oluşturuldu`);

  return { urun, kategoriVeUrunler, gonderi };
}

// =============================================
// READ İşlemleri
// =============================================
async function okumaIslemleri() {
  console.log('
=== READ İşlemleri ===
');

  // 1. Tek kayıt bulma
  const kullanici = await prisma.kullanici.findUnique({
    where: { email: 'yazar@ornek.com' },
    include: {
      profil: true,
      _count: {
        select: {
          gonderiler: true,
          yorumlar: true
        }
      }
    }
  });
  console.log('Kullanıcı:', kullanici?.ad, kullanici?.soyad);
  console.log('Gönderi sayısı:', kullanici?._count.gonderiler);

  // 2. Filtreleme ve sıralama
  const urunler = await prisma.urun.findMany({
    where: {
      AND: [
        { aktif: true },
        { stok: { gt: 0 } },
        {
          OR: [
            { fiyat: { lte: 500 } },
            { kategori: { slug: 'elektronik' } }
          ]
        }
      ]
    },
    select: {
      id: true,
      ad: true,
      fiyat: true,
      stok: true,
      kategori: {
        select: { ad: true }
      }
    },
    orderBy: [
      { fiyat: 'asc' }
    ],
    take: 10
  });
  console.log('Uygun ürünler:', urunler.length);
  urunler.forEach(u => {
    console.log(`  - ${u.ad}: ${u.fiyat} TL (Stok: ${u.stok})`);
  });

  // 3. Metin araması
  const aramaKelimesi = 'kulaklık';
  const aramaSonuclari = await prisma.urun.findMany({
    where: {
      OR: [
        { ad: { contains: aramaKelimesi, mode: 'insensitive' } },
        { aciklama: { contains: aramaKelimesi, mode: 'insensitive' } }
      ]
    }
  });
  console.log(`"${aramaKelimesi}" araması: ${aramaSonuclari.length} sonuç`);

  // 4. Sayfalama (cursor-based)
  const ilkSayfa = await prisma.urun.findMany({
    take: 5,
    orderBy: { id: 'asc' }
  });

  if (ilkSayfa.length > 0) {
    const sonId = ilkSayfa[ilkSayfa.length - 1].id;
    const ikinciSayfa = await prisma.urun.findMany({
      take: 5,
      skip: 1,
      cursor: { id: sonId },
      orderBy: { id: 'asc' }
    });
    console.log('İkinci sayfa:', ikinciSayfa.length, 'ürün');
  }

  // 5. Gruplama ve toplama
  const kategorIstatistik = await prisma.urun.groupBy({
    by: ['aktif'],
    _count: { id: true },
    _sum: { stok: true },
    _avg: { fiyat: true },
    _min: { fiyat: true },
    _max: { fiyat: true }
  });
  console.log('İstatistikler:', JSON.stringify(kategorIstatistik, null, 2));

  // 6. Toplam kayıt sayısı
  const toplamUrun = await prisma.urun.count({
    where: { aktif: true }
  });
  console.log('Toplam aktif ürün:', toplamUrun);
}

// =============================================
// UPDATE İşlemleri
// =============================================
async function guncellemeIslemleri() {
  console.log('
=== UPDATE İşlemleri ===
');

  // 1. Tek kayıt güncelleme
  const guncellenen = await prisma.urun.update({
    where: { sku: 'KLK-001' },
    data: {
      fiyat: 399.99,
      aciklama: 'Bluetooth 5.3 destekli, gürültü engellemeli kulaklık'
    }
  });
  console.log('Güncellenen ürün:', guncellenen.ad, '- Yeni fiyat:', guncellenen.fiyat);

  // 2. Upsert (varsa güncelle, yoksa oluştur)
  const upsertSonuc = await prisma.kategori.upsert({
    where: { slug: 'giyim' },
    update: {
      aciklama: 'Güncellenmiş giyim kategorisi açıklaması'
    },
    create: {
      ad: 'Giyim',
      slug: 'giyim',
      aciklama: 'Erkek ve kadın giyim ürünleri'
    }
  });
  console.log('Upsert sonucu:', upsertSonuc.ad);

  // 3. Çoklu güncelleme
  const cokluGuncelleme = await prisma.urun.updateMany({
    where: {
      stok: { lte: 10 },
      aktif: true
    },
    data: {
      aktif: false
    }
  });
  console.log(`${cokluGuncelleme.count} ürün pasife alındı (düşük stok)`);

  // 4. Sayısal alan artırma/azaltma
  const stokGuncelle = await prisma.urun.update({
    where: { sku: 'SAT-001' },
    data: {
      stok: { decrement: 5 },
      goruntuSayisi: { increment: 1 }
    }
  });
  console.log('Stok güncellendi:', stokGuncelle.ad, '- Kalan:', stokGuncelle.stok);

  // 5. İlişkili verileri güncelleme
  const gonderiGuncelle = await prisma.gonderi.update({
    where: { slug: 'prisma-veritabani-yonetimi' },
    data: {
      durum: 'YAYINDA',
      etiketler: {
        create: [{
          etiket: {
            connectOrCreate: {
              where: { slug: 'veritabani' },
              create: { ad: 'Veritabanı', slug: 'veritabani' }
            }
          }
        }]
      }
    },
    include: {
      etiketler: { include: { etiket: true } }
    }
  });
  console.log('Gönderi güncellendi. Etiketler:',
    gonderiGuncelle.etiketler.map(e => e.etiket.ad).join(', '));
}

// =============================================
// DELETE İşlemleri
// =============================================
async function silmeIslemleri() {
  console.log('
=== DELETE İşlemleri ===
');

  // 1. Tek kayıt silme
  try {
    const silinen = await prisma.urun.delete({
      where: { sku: 'TAB-001' }
    });
    console.log('Silinen ürün:', silinen.ad);
  } catch (hata) {
    console.log('Silme hatası:', hata.message);
  }

  // 2. Koşullu çoklu silme
  const cokluSilme = await prisma.urun.deleteMany({
    where: {
      aktif: false,
      stok: 0
    }
  });
  console.log(`${cokluSilme.count} pasif ürün silindi`);
}

// =============================================
// Transaction İşlemleri
// =============================================
async function transactionOrnekleri() {
  console.log('
=== Transaction İşlemleri ===
');

  // İnteraktif transaction
  try {
    const sonuc = await prisma.$transaction(async (tx) => {
      // Ürünü bul
      const urun = await tx.urun.findUnique({
        where: { sku: 'KLK-001' }
      });

      if (!urun || urun.stok < 2) {
        throw new Error('Yetersiz stok!');
      }

      // Stoku azalt
      const guncelUrun = await tx.urun.update({
        where: { id: urun.id },
        data: { stok: { decrement: 2 } }
      });

      // Sipariş oluştur
      const siparis = await tx.siparis.create({
        data: {
          musteriId: 1,
          toplamTutar: urun.fiyat * 2,
          durum: 'BEKLEMEDE',
          kalemler: {
            create: {
              urunId: urun.id,
              adet: 2,
              birimFiyat: urun.fiyat
            }
          }
        }
      });

      return { siparis, kalanStok: guncelUrun.stok };
    });

    console.log('Sipariş oluşturuldu. Kalan stok:', sonuc.kalanStok);
  } catch (hata) {
    console.error('Transaction hatası:', hata.message);
  }
}

// Ana fonksiyon
async function main() {
  try {
    await olusturmaIslemleri();
    await okumaIslemleri();
    await guncellemeIslemleri();
    await silmeIslemleri();
    await transactionOrnekleri();
  } catch (hata) {
    console.error('Genel hata:', hata.message);
  } finally {
    await prisma.$disconnect();
    console.log('
Veritabanı bağlantısı kapatıldı');
  }
}

main();

Prisma ile CRUD işlemleri, tip güvenliği ve sezgisel API sayesinde hem güvenli hem de verimli bir şekilde gerçekleştirilebilir. Özellikle iç içe yazma işlemleri, akıllı filtreleme operatörleri ve transaction desteği, karmaşık iş mantığını temiz bir şekilde kodlamanıza olanak tanır. Prisma'nın otomatik üretilen istemcisi sayesinde geliştirme sürecinde hata yapma olasılığınız minimuma iner.
 
Emeğiniz ve katkınız için teşekkür ederiz!
Konunuz gerekli incelemelerden geçerek onaylandı. Topluluğumuza katkılarınızın devamını bekliyoruz.
İyi forumlar! 🎉
 
Son düzenleme:

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst