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!
[NODE JS] Sequelize ORM ile Veritabanı İşlemleri
ORM (Object-Relational Mapping) kavramıyla ilk tanıştığımda, veritabanı ile uygulama arasındaki köprünün ne kadar zarif olabileceğini anlamıştım. Sequelize, Node.js ekosistemindeki en olgun ve yaygın kullanılan ORM kütüphanesidir. PostgreSQL, MySQL, MariaDB, SQLite ve Microsoft SQL Server gibi farklı veritabanlarını destekler. Bu çoklu destek, projenizin büyümesiyle veritabanı değişikliği yapmanız gerektiğinde hayat kurtarıcı olabilir.
Sequelize'ın en büyük avantajı, ham SQL yazmadan veritabanı işlemlerini JavaScript nesneleri ve metodlarıyla gerçekleştirebilmemiz. Model tanımları, ilişkiler, sorgular, doğrulamalar — hepsini JavaScript koduyla ifade ederiz. Bu yaklaşım, özellikle SQL'e çok aşina olmayan geliştiriciler için büyük kolaylık sağlar. Ancak karmaşık sorgularda ham SQL'e dönmek gerekebilir ve Sequelize buna da olanak tanır.
Model tanımlama, Sequelize'ın temelini oluşturur. Her model, veritabanındaki bir tabloya karşılık gelir. Model alanlarının türlerini, doğrulama kurallarını, varsayılan değerlerini ve diğer özelliklerini tanımlarız. DataTypes modülü, STRING, INTEGER, FLOAT, BOOLEAN, DATE, JSON, ENUM gibi birçok veri türünü destekler.
Doğrulama (validation) konusunda Sequelize çok güçlü. Her alan için birden fazla doğrulama kuralı tanımlayabiliriz: isEmail, isURL, isNumeric, len, min, max gibi yerleşik doğrulayıcılar mevcuttur. Ayrıca özel doğrulayıcı fonksiyonlar da yazabiliriz. Bu doğrulamalar, verinin veritabanına kaydedilmeden önce kontrol edilmesini sağlar.
Hook'lar (yaşam döngüsü kancaları), Sequelize'ın güçlü özelliklerinden biridir. beforeCreate, afterCreate, beforeUpdate, afterUpdate gibi kancalar, model işlemleri öncesinde veya sonrasında ek mantık eklememize olanak tanır. Örneğin, kullanıcı oluşturulmadan önce şifreyi hashlemek veya bir kayıt silindikten sonra ilgili dosyaları temizlemek gibi işlemler hook'larla yapılabilir.
Scope'lar, sık kullanılan sorgu filtrelerini tanımlamamıza yarar. Varsayılan scope ve adlandırılmış scope'lar kullanarak kod tekrarını azaltabiliriz. Örneğin, sadece aktif kayıtları getiren bir scope tanımlayıp tüm sorgularda kullanabiliriz.
JavaScript:
// Sequelize ORM ile Veritabanı İşlemleri
const { Sequelize, DataTypes, Op, Model } = require('sequelize');
// Veritabanı bağlantısı
const sequelize = new Sequelize('egitim_db', 'kullanici', 'sifre', {
host: 'localhost',
dialect: 'postgres', // veya 'mysql', 'sqlite', 'mssql'
logging: (msg) => console.log(`[SQL] ${msg}`),
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
define: {
timestamps: true, // createdAt ve updatedAt otomatik
underscored: true, // snake_case sütun isimleri
freezeTableName: true // Tablo ismini çoğullaştırma
}
});
// Kullanıcı Modeli
class Kullanici extends Model {
// Örnek metod
tamIsim() {
return `${this.ad} ${this.soyad}`;
}
// Sınıf metodu
static async aktifKullanicilariGetir() {
return await this.scope('aktif').findAll();
}
}
Kullanici.init({
ad: {
type: DataTypes.STRING(50),
allowNull: false,
validate: {
notEmpty: { msg: 'İsim boş olamaz' },
len: { args: [2, 50], msg: 'İsim 2-50 karakter arasında olmalıdır' }
}
},
soyad: {
type: DataTypes.STRING(50),
allowNull: false,
validate: {
notEmpty: { msg: 'Soyad boş olamaz' }
}
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: { msg: 'Bu e-posta adresi zaten kayıtlı' },
validate: {
isEmail: { msg: 'Geçerli bir e-posta adresi giriniz' }
}
},
sifre: {
type: DataTypes.STRING,
allowNull: false,
validate: {
len: { args: [8, 100], msg: 'Şifre en az 8 karakter olmalıdır' }
}
},
telefon: {
type: DataTypes.STRING(15),
validate: {
is: { args: /^[0-9+\-\s]+$/, msg: 'Geçerli bir telefon numarası giriniz' }
}
},
dogumTarihi: {
type: DataTypes.DATEONLY,
validate: {
isDate: { msg: 'Geçerli bir tarih giriniz' },
isBefore: {
args: new Date().toISOString().split('T')[0],
msg: 'Doğum tarihi bugünden önce olmalıdır'
}
}
},
rol: {
type: DataTypes.ENUM('kullanici', 'moderator', 'admin'),
defaultValue: 'kullanici'
},
aktif: {
type: DataTypes.BOOLEAN,
defaultValue: true
},
sonGirisTarihi: {
type: DataTypes.DATE
}
}, {
sequelize,
modelName: 'Kullanici',
tableName: 'kullanicilar',
// Scope tanımları
scopes: {
aktif: { where: { aktif: true } },
adminler: { where: { rol: 'admin' } },
sonKayitlar: {
order: [['created_at', 'DESC']],
limit: 10
}
},
// Hook tanımları
hooks: {
beforeCreate: async (kullanici) => {
// Şifre hashleme simülasyonu
console.log(`Şifre hashleniyor: ${kullanici.ad}`);
// Gerçek uygulamada: kullanici.sifre = await bcrypt.hash(kullanici.sifre, 12);
},
afterCreate: (kullanici) => {
console.log(`Yeni kullanıcı oluşturuldu: ${kullanici.tamIsim()}`);
}
}
});
// Gönderi Modeli
class Gonderi extends Model {}
Gonderi.init({
baslik: {
type: DataTypes.STRING(200),
allowNull: false,
validate: {
notEmpty: true,
len: [5, 200]
}
},
icerik: {
type: DataTypes.TEXT,
allowNull: false
},
durum: {
type: DataTypes.ENUM('taslak', 'yayinda', 'arsivlendi'),
defaultValue: 'taslak'
},
goruntulemeSayisi: {
type: DataTypes.INTEGER,
defaultValue: 0
},
etiketler: {
type: DataTypes.JSON,
defaultValue: []
},
yayinTarihi: {
type: DataTypes.DATE
}
}, {
sequelize,
modelName: 'Gonderi',
tableName: 'gonderiler'
});
// Yorum Modeli
class Yorum extends Model {}
Yorum.init({
icerik: {
type: DataTypes.TEXT,
allowNull: false,
validate: {
len: [1, 1000]
}
},
onaylandi: {
type: DataTypes.BOOLEAN,
defaultValue: false
}
}, {
sequelize,
modelName: 'Yorum',
tableName: 'yorumlar'
});
// İlişki tanımları
Kullanici.hasMany(Gonderi, { foreignKey: 'yazarId', as: 'gonderiler' });
Gonderi.belongsTo(Kullanici, { foreignKey: 'yazarId', as: 'yazar' });
Gonderi.hasMany(Yorum, { foreignKey: 'gonderiId', as: 'yorumlar' });
Yorum.belongsTo(Gonderi, { foreignKey: 'gonderiId' });
Kullanici.hasMany(Yorum, { foreignKey: 'yazarId', as: 'yorumlarim' });
Yorum.belongsTo(Kullanici, { foreignKey: 'yazarId', as: 'yorumYazari' });
// CRUD İşlemleri
async function crudIslemleri() {
// Tabloları senkronize et
await sequelize.sync({ force: true });
// CREATE - Oluşturma
const kullanici1 = await Kullanici.create({
ad: 'Emre',
soyad: 'Yılmaz',
email: 'emre@ornek.com',
sifre: 'guvenli_sifre_123',
telefon: '+90 555 123 4567',
dogumTarihi: '1995-03-15',
rol: 'admin'
});
console.log('Kullanıcı oluşturuldu:', kullanici1.tamIsim());
// Toplu oluşturma
const kullanicilar = await Kullanici.bulkCreate([
{ ad: 'Selin', soyad: 'Kaya', email: 'selin@ornek.com', sifre: 'sifre12345' },
{ ad: 'Can', soyad: 'Demir', email: 'can@ornek.com', sifre: 'sifre12345' },
{ ad: 'Deniz', soyad: 'Öztürk', email: 'deniz@ornek.com', sifre: 'sifre12345' }
], { validate: true });
console.log(`${kullanicilar.length} kullanıcı toplu oluşturuldu`);
// Gönderi oluşturma
const gonderi = await Gonderi.create({
baslik: 'Node.js ile Veritabanı İşlemleri',
icerik: 'Sequelize ORM kullanarak veritabanı işlemleri...',
yazarId: kullanici1.id,
durum: 'yayinda',
etiketler: ['nodejs', 'sequelize', 'veritabanı'],
yayinTarihi: new Date()
});
// READ - Okuma
const tumKullanicilar = await Kullanici.findAll({
where: { aktif: true },
attributes: ['id', 'ad', 'soyad', 'email', 'rol'],
order: [['ad', 'ASC']]
});
console.log('Aktif kullanıcılar:', tumKullanicilar.length);
// İlişkili veriyle sorgulama
const gonderiDetay = await Gonderi.findOne({
where: { id: gonderi.id },
include: [
{ model: Kullanici, as: 'yazar', attributes: ['ad', 'soyad'] },
{ model: Yorum, as: 'yorumlar', include: [
{ model: Kullanici, as: 'yorumYazari', attributes: ['ad'] }
]}
]
});
console.log('Gönderi:', gonderiDetay.baslik, '- Yazar:', gonderiDetay.yazar.ad);
// Operatörlerle filtreleme
const filtrelenmis = await Kullanici.findAll({
where: {
[Op.or]: [
{ rol: 'admin' },
{ ad: { [Op.like]: '%e%' } }
],
aktif: true
}
});
console.log('Filtrelenmiş kullanıcılar:', filtrelenmis.length);
// UPDATE - Güncelleme
await kullanici1.update({ sonGirisTarihi: new Date() });
console.log('Giriş tarihi güncellendi');
await Kullanici.update(
{ aktif: false },
{ where: { sonGirisTarihi: { [Op.lt]: new Date('2025-01-01') } } }
);
// DELETE - Silme
await Yorum.destroy({ where: { onaylandi: false } });
console.log('Onaylanmamış yorumlar silindi');
}
// Transaction ile güvenli işlem
async function guvenliIslem() {
const t = await sequelize.transaction();
try {
const kullanici = await Kullanici.findOne({
where: { email: 'emre@ornek.com' },
transaction: t
});
const yeniGonderi = await Gonderi.create({
baslik: 'Transaction Örneği',
icerik: 'Bu gönderi transaction içinde oluşturuldu',
yazarId: kullanici.id,
durum: 'yayinda'
}, { transaction: t });
await t.commit();
console.log('Transaction başarılı');
} catch (hata) {
await t.rollback();
console.error('Transaction geri alındı:', hata.message);
}
}
// Ana fonksiyon
async function main() {
try {
await sequelize.authenticate();
console.log('Veritabanı bağlantısı başarılı');
await crudIslemleri();
await guvenliIslem();
} catch (hata) {
console.error('Hata:', hata.message);
} finally {
await sequelize.close();
}
}
main();
Sequelize ORM, Node.js projelerinde veritabanı işlemlerini büyük ölçüde kolaylaştıran güçlü bir araçtır. Model tanımları, doğrulamalar, ilişkiler ve hook'lar gibi özellikleriyle profesyonel uygulamalar geliştirmek için gereken her şeyi sunar. Başlangıçta öğrenme eğrisi biraz dik olabilir ama bir kez kavradığınızda geliştirme hızınız ciddi şekilde artacaktır.
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!
Konunuz gerekli incelemelerden geçerek onaylandı. Topluluğumuza katkılarınızın devamını bekliyoruz.
İyi forumlar!

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 1
- Görüntüleme
- 12
- Cevaplar
- 9
- Görüntüleme
- 473
- Cevaplar
- 8
- Görüntüleme
- 1K
