Battle of the Node.js ORMs: Sequelize در مقابل TypeORM

کتابخانه های محبوب Object-Relational Mapping (ORM) برای Node.js شامل Sequelize و TypeORM هستند. هر دوی این کتابخانه ها سطح بالاتری از انتزاع را نسبت به پایگاه داده های رابطه ای ارائه می دهند و با ارائه یک API کاربرپسند، عملیات پایگاه داده را ساده می کنند.
در حالی که شباهت های متعددی در بین این کتابخانه ها وجود دارد، واریانس های قابل توجهی نیز وجود دارد. برخی از مهم ترین تفاوت های بین Sequelize و TypeORM در این پست مورد بحث قرار خواهند گرفت.
پشتیبانی از زبان
پشتیبانی زبان ارائه شده توسط Sequelize و TypeORM یکی از تمایزات کلیدی آنهاست. در مقایسه با TypeORM، Sequelize از TypeScript و همچنین JavaScript پشتیبانی می کند.
بنابراین اگر روی یک پروژه مبتنی بر جاوا اسکریپت کار می کنید، Sequelize ممکن است گزینه بهتری برای شما باشد. با این حال، اگر از TypeScript استفاده می کنید، TypeORM ممکن است انتخاب بهتری باشد.
پرس و جو
تفاوت دیگر Sequelize و TypeORM در نحوه رسیدگی به پرس و جوها است. Sequelize از یک سازنده پرس و جو استفاده می کند که به شما امکان می دهد پرس و جوهای پیچیده را با استفاده از جاوا اسکریپت یا TypeScript بسازید. از سوی دیگر، TypeORM از یک الگوی مخزن استفاده می کند، که به شما امکان می دهد عملیات اصلی CRUD (ایجاد، خواندن، به روز رسانی، حذف) را با استفاده از روش هایی مانند انجام دهید. find
، findOne
، save
، update
، و delete
.
هر دو روش دارای مزایایی هستند، با این حال، طراحی مخزن TypeORM ممکن است برای عملیات ساده CRUD آسان تر باشد، در حالی که مکانیسم سازنده پرس و جو Sequelize ممکن است برای پرس و جوهای پیچیده تر مناسب تر باشد.
روابط
شما می توانید با استفاده از Sequelize و TypeORM روابط یک به چند، چند به چند و یک به یک را بین جداول در پایگاه داده خود مشخص کنید. با این حال، آنها روابط را متفاوت مدیریت می کنند.
Sequelize روابط را با استفاده از یک روش مرسوم تعریف می کند، که در آن محدودیت کلید خارجی در تعریف مهاجرت یا مدل مشخص می شود. از سوی دیگر، TypeORM از روش شناسی مدرن تری استفاده می کند که در آن روابط با استفاده از دکوراتورها در طراحی مدل شما تعریف می شود.
این نشان میدهد که Sequelize میتواند گزینه بهتری برای شما باشد، اگر میخواهید روشی مرسومتر برای تعریف روابط داشته باشید. با این وجود، اگر استراتژی مدرن تری انتخاب کنید، TypeORM می تواند انتخاب بهتری باشد.
پشتیبانی از سایر پایگاه های داده
پشتیبانی آنها از پایگاه داده های مختلف تمایز دیگری بین Sequelize و TypeORM است. علیرغم این واقعیت که هر دو کتابخانه از انواع پایگاه های داده پشتیبانی می کنند، Sequelize پشتیبانی گسترده تری را برای پایگاه های داده بیشتر، مانند MySQL
، PostgreSQL
، SQLite
، و Microsoft SQL Server
. برعکس، MySQL
، PostgreSQL
، MariaDB
، SQLite
، Oracle
، Microsoft SQL Server
، و MongoDB
همه توسط TypeORM پشتیبانی می شوند.
اگر از پایگاه داده خاصی استفاده می کنید که هیچ یک از کتابخانه ها از آن پشتیبانی نمی کند، این می تواند یک مورد بسیار مهم باشد.
نمونه CRUD با استفاده از هر دو ORM
به دنبال مثال
در اینجا مثالی از نحوه ایجاد یک مدل و انجام عملیات CRUD در جدول پایگاه داده با استفاده از Sequelize آورده شده است:
const { Sequelize, Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'
});
class User extends Model {}
User.init({
firstName: DataTypes.STRING,
lastName: DataTypes.STRING,
email: DataTypes.STRING
}, { sequelize, modelName: 'user' });
(async () => {
await sequelize.sync();
const user = await User.create({ firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' });
console.log(user.toJSON());
const users = await User.findAll();
console.log(users.map(user => user.toJSON()));
})();
این کد یک اتصال به پایگاه داده MySQL برقرار می کند، a را تعریف می کند User
مدل با سه ویژگی، مدل را با پایگاه داده همگام می کند، یک رکورد کاربری جدید ایجاد می کند، همه کاربران را از پایگاه داده بازیابی می کند و نتایج را در کنسول ثبت می کند.
نمونه TypeORM
در اینجا مثالی از استفاده از TypeORM برای تعریف یک مدل و انجام عملیات CRUD در جدول پایگاه داده آورده شده است:
import { createConnection } from 'typeorm';
@Entity()
class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column()
email: string;
}
(async () => {
const connection = await createConnection();
const user = new User();
user.firstName = 'John';
user.lastName = 'Doe';
user.email = 'john.doe@example.com';
await connection.manager.save(user);
console.log(user);
const users = await connection.manager.find(User);
console.log(users);
})();
با ایجاد یک رکورد کاربری جدید، ساختن a User
موجودیت با سه ویژگی، استخراج همه کاربران از پایگاه داده، و ثبت نتایج به کنسول، این برنامه به یک پایگاه داده عادی MySQL متصل می شود.
همانطور که می بینید، هر دو Sequelize و TypeORM API های مشابهی را برای تعریف مدل ها / موجودیت ها و انجام عملیات CRUD در جدول پایگاه داده ارائه می دهند. با این حال، نحو و رویکرد به دلیل انتخاب زبان و طراحی انجام شده توسط هر کتابخانه متفاوت است.
نمونه جدول رابطه با استفاده از هر دو ORM
نمونه TypeORM
را بگیرید User
و Post
اشیاء به عنوان مثال هر پست دارای یک مالک است و هر کاربر مجاز است چندین پست داشته باشد. در اینجا نحوه بیان این رابطه با استفاده از TypeORM آمده است:
@Entity()
class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => Post, post => post.user)
posts: Post[];
}
@Entity()
class Post {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
content: string;
@ManyToOne(() => User, user => user.posts)
user: User;
}
در User
موجودیت، رابطه یک به چند را با آن تعریف می کنیم Post
با استفاده از @OneToMany
دکوراتور ما مشخص می کنیم که رابطه به است Post
موجودیت و اینکه مربوط به آن است user
اموال در Post
وجود، موجودیت.
در Post
موجودیت، ما یک رابطه چند به یک با آن تعریف می کنیم User
با استفاده از @ManyToOne
دکوراتور ما مشخص می کنیم که رابطه به است User
موجودیت و اینکه مربوط به آن است posts
اموال در User
وجود، موجودیت.
با این تنظیمات، میتوانیم یک کاربر و همه پستهایش را به این صورت واکشی کنیم:
const user = await connection.manager.findOne(User, 1, { relations: { posts: true } });
این کاربر را با شناسه 1 واکشی می کند و مشتاقانه همه پست های او را بارگیری می کند.
به دنبال مثال
در اینجا نحوه تعریف همان رابطه با استفاده از Sequelize آمده است:
const { Sequelize, Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'
});
class User extends Model {}
User.init({
name: DataTypes.STRING
}, { sequelize, modelName: 'user' });
class Post extends Model {}
Post.init({
title: DataTypes.STRING,
content: DataTypes.STRING
}, { sequelize, modelName: 'post' });
User.hasMany(Post);
Post.belongsTo(User);
در این مثال، ما را تعریف می کنیم User
و Post
مدل هایی با استفاده از Model.init
. سپس رابطه بین دو مدل را با استفاده از عبارت تعریف می کنیم User.hasMany(Post)
و Post.belongsTo(User)
مواد و روش ها.
با این تنظیمات، میتوانیم یک کاربر و همه پستهایش را به این صورت واکشی کنیم:
const user = await User.findByPk(1, { include: [Post] });
این کاربر را با شناسه 1 واکشی می کند و مشتاقانه همه پست های او را بارگیری می کند.