Sequelize Nedir?
Sequelize, NodeJs tabanlı bir ORM (Object-Relational Mapping) yazılımıdır. Veritabanı yapılarını Obje ve onun fonksiyonlarına çevirerek, kod içerisinde direkt SQL query’leri yazmadan, kod tarafında işin halledilme olayıdır kısaca. Yani veritabanı bizim bir objemiz olur ve orm’deki methodlar vasıtasıyla CRUD işlemleri gerçekleştirebiliriz.
Sequelize’da 4 adet ilişki türü vardır, bunlar hasOne,hasMany,belongsTo ve belongsToMany’dir. SQL tablolarımızdaki ilişkilerimizden yola çıkarak relationship yapısını bu dört yöntem/method ile halledebiliriz. Bunların kullanım mantığı, tablomuzdaki target(hedef) ve source(kaynak) tablo yapısına göre ayarlanır. Şimdi yazımızın en önemli kısımlarından biri olan target ve source tablomuz hakkında konuşalım.
Target ve Source'u Belirleme
Yukarıdaki örnek instructor ve subject tablomuza baktığımızda, bir one to one relationship örneği görüyoruz. Bu tabloda bizim target yani hedef tablomuz, Instructor tablosu ve source yani kaynak tablomuz Subject tablosu. Subject(source) tablosundan Instructor(target) tablosuna bir one-to-one ilişkimiz var.
Aşağıdaki tablomuzda ise gördüğümüz üzere bir one to many ilişkimiz var ve görüldüğü üzere Instructor’dan Class’a gidiyoruz, yani burada ise Instructor tablomuzun bizim source tablomuz olduğunu ve Class tablomuzun target tablomuz olduğunu görüyoruz.
Aynı şekilde many to many tablomuz da benzer bir ilişki içerisinde. Burada ise Student ve Class tablolarımız bizim source tablolarımız ve aradaki orta tablomuz ise bizim target tablomuz.
Source ve Target tablomuzu nasıl belirlediğimizi bulduktan sonra sırada bu dört ilişkiyi nasıl kullanabileceğimiz kuralına geliyoruz. Bu kural iki adet maddeden oluşuyor ve sequelize’da relationship’leri ayarlamamız için bu iki kural’dan yola çıkacağız.
Kurallar
- Her zaman source tablosundan target tablomuza doğru yola çıkacağız. Bu bağlamda doğru bir ilişkimiz olması için, source tablomuzu iyi belirlemeliyiz.
[ Source model ] . [ İlişki Türü ] ([ Target model ],options objesi)
- Bu kuralımızda, foreign key yani yabancı anahtarımızın hangi tabloda olacağına bakacağız.
- Eğer bizim yabancı anahtarımız source model’imizin içerisinde ise, belongsTo veya belongsToMany kullanacağız.
- Eğer bizim yabancı anahtarımızın target model’imizin içerisinde ise, hasMany ve hasOne anahtar kelimesini kullanacağız.
Yani bu kurallardan yola çıkarak şöyle özetleyebiliriz; Eğer bizim yabancı anahtarımız, ana tabloda ise, belongsTo veya belontsToMany kullanıyoruz, eğer karşı tabloda ise hasOne ve hasMany kullanıyoruz.
Tablomuz Ve İlişkilerimiz
Yukarıdaki veritabanı tasarımımızda source ve target tablolarını belirleyerek işe başlıyoruz.
- Subject’den Instructor’a One to One ilişki, Subject burada bizim source tablomuz, Instructor burada bizim target tablomuz. Foreign Key’in Instructor tablosu yani target içinde olduğunu görüyoruz, yani burada ilişkimiz Subject.hasOne(Instructor) şeklinde olacak. Tam tersi bir şekilde bağlamak için ise Instructor.belongsTo(Subject) olacak.
- Instructor’dan Class’a bir One to Many ilişkimiz var. Instructor burada bizim source tablomuz, Class ise target tablomuz. Yani burada ilişkimiz Instructor.hasMany(Class) şeklinde olacak. Ve yine, Class’tan da Instructor tablosuna erişebilmek istersek eğer Class.belongsTo(Instructor) bağlantısı verebiliriz. Neden belonsTo kullanabildik? Çünkü bu şekilde Source tablomuz’u değiştirdik ve Foreign key source tablosuna taşındığı için belongsTo kullandık.
- Student Class ilişkimiz ise Many to Many bir ilişki fakat burada bir ara tablo olduğu için, burada diğer kuralları biraz ihlal etmiş olacağız, bu bizden değil sequelize’ın kendi yapısından kaynaklanan bir kural.. Student ve Class tablolarımız burada bizim source yani kaynak tablolarımız olmasına rağmen, burada bir ara tablo olduğu için, belongsToMany kullanmak zorundayız. Student.belongsToMany(Class) yapısını kullanacağız.
Kurulum
Eğer bir sequelize projesini nasıl kuracağınızı merak ediyorsanız, MDP’de yazılım geliştirici olan Burak Yılmazer’in
Sequelize Nedir yazısına ulaşarak, kurulumu yapabilirsiniz. Bizim burada asıl amacımız sequelize’da ilişkileri kullanarak bir örnek yapmak. Bu yüzden kurulum adımlarını atlıyorum.
Komut satırından ‘sequelize init’ yaparak projemizi başlatıyoruz ve bize bir proje yapısı getiriyor. Bu proje yapımız, config,migrations,models şeklinde geliyor. app.js’i projeyi test etmek ve route’ları ayarlamak için kendim oluşturdum.
İlk olarak işe config.json’ı ayarlayarak başlıyoruz. Bu dosyayı doğru ayarlamamız veritabanına bağlanabilmemiz için önemli. Ben aşağıda gördüğünüz gibi lokal ortamımdaki postgres’e bu şekilde bağlandım. Developmen modda çalışacağımız için sadece development modu değiştirsek şimdilik yeterli olur.
Komut satırından sequelize db:create diyerek database’imizi postgres içerisinde sequelize orm paketimiz aracılığıyla oluşturuyoruz.
Model oluşturmak
Model’lerimizi oluşturarak işe başlıyoruz. Bu model’ler bizim SQL’de entity diye tabir ettiğimiz verilerdir.
Şu kodları sırasıyla yazarak Modellerimizi oluşturabiliriz.
Student’imiz name,surname ve email alacak ve class harici bir yere bağlı olmayacak, o modeli şu şekilde oluşturuyoruz:
sequelize model generate --name Student --attributes name:string,surname:string,email:string
Class’ımız hem Instructor’a hem de Student’a bağlı olacak. İçinde foreign key olarak instructorId tutacak yani class’a bir sorgu attığımızda instructorId’de beraberinde gelecek.O modeli bu şekilde oluşturuyoruz.
sequelize model:generate --name Class --attributes instructorId:integer,classCode:string
StudentClass tablomuz many-to-many ilişki içinde olduğundan dolayı, bir ara tablo sayılacak ve classId ve studentId’yi tutacak.Onu bu şekilde oluşturabiliriz:
sequelize model:generate --name StudentClass --attributes classId:integer,studentId:integer
Instructor ile Subject arasında bir One to One ilişki olduğu için, Instuctor’ın içinde bir foreign key olan SubjectId’yi tutuyoruz. Böylece Instrutor’a sorgu attığımızda bize subjectId’yi de getirecek, böylece sequelize’dan tek sorgu’da her iki özelliğe de ulaşabileceğiz. Kodu şu şekilde oluşturabiliriz.
sequelize model:generate --name Instructor --attributes instructorDegree:string,name:string,surname:string,subjectId:integer
Son olarak Subject öğretmenlerde belirtileceği için, sadece name içerek, kodunu bu şekilde oluşturabiliriz:
sequelize model:generate --name Subject --attributes subjectName:string
Daha sonra komut satırından db:migrate komutunu çalıştırdığımızda, bu modeller üzerinde migration oluşturup, modeli kalıcı olarak database’e kaydeder. Şuraya dikkat etmekte fayda var, model isimlerini her ne kadar tekil olarak kod üzerinde generate(oluşturmak) etsek de, bunlar SQL’de çoğul ve büyük harf olarak geçebilir, bunun da çözümü, eğer tabloda bir bütünlük sağlamak istiyorsak, daha sonradan bu class’a tableName parametresi vererek bu bütünlüğü sağlabiliriz.
Örnek bir student tablosunun model ve tablo name’i şu şekilde olabilir: