از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
استفاده از Sequelize ORM با Node.js و ExpressSequelize یک ORM محبوب است که برای Node.js ایجاد شده است، و در این آموزش از آن برای ساخت یک CRUD API برای مدیریت یادداشت ها استفاده خواهیم کرد. تعامل با پایگاه های داده یک کار رایج برای برنامه های کاربردی باطن است. این معمولاً از طریق پرسوجوهای SQL خام انجام میشود، که ساختن آن میتواند دشوار باشد، به خصوص…
سرفصلهای مطلب
معرفی
عاقبت سازی یک ORM محبوب است که برای Node.js ایجاد شده است، و در این آموزش از آن برای ایجاد یک CRUD API برای مدیریت یادداشت ها استفاده می کنیم.
تعامل با پایگاه های داده یک کار رایج برای برنامه های کاربردی باطن است. این معمولاً از طریق پرسوجوهای SQL خام انجام میشود، که ساختن آن میتواند دشوار باشد، بهویژه برای کسانی که تازه به SQL یا به طور کلی پایگاههای دادهاند.
در نهایت، نگاشتهای رابطه ای شی (ORM ها) به وجود آمدند – طراحی شدند تا مدیریت پایگاه داده ها را آسان تر کنند. آنها به طور خودکار اشیاء (موجودات) را از کد ما در یک پایگاه داده رابطه ای ترسیم می کنند، همانطور که از نام آن پیداست.
دیگر پرس و جوهای SQL خام را نمی نویسیم و آنها را در پایگاه داده اجرا نمی کنیم. با ارائه یک روش برنامهنویسی برای اتصال کد خود به پایگاه داده و دستکاری دادههای ماندگار، میتوانیم تمرکز بیشتری داشته باشیم. روی منطق کسب و کار و کمتر روی SQL مستعد خطا
ORM چیست؟
نگاشت رابطه ای شی تکنیکی است که اشیاء نرم افزار را به جداول پایگاه داده نگاشت می کند. توسعهدهندگان میتوانند با اشیا تعامل داشته باشند، بهجای اینکه مجبور باشند در واقع هر درخواست پایگاه داده بنویسند. هنگامی که یک شی خوانده می شود، ایجاد می شود، به روز می شود، یا حذف می شود، ORM یک پرس و جو پایگاه داده را در زیر هود می سازد و اجرا می کند.
یکی دیگر از مزایای ORM ها پشتیبانی از چندین پایگاه داده است: Postgres، MySQL، SQLiteو غیره. اگر برنامه ای را با استفاده از پرس و جوهای خام بنویسید، انتقال به پایگاه داده دیگری دشوار خواهد بود زیرا بسیاری از پرس و جوها باید دوباره نوشته شوند.
با یک ORM، تغییر پایگاه داده توسط خود ORM انجام می شود و معمولاً تنها کاری که باید انجام دهید این است که یک یا دو مقدار را در یک فایل پیکربندی تغییر دهید.
عاقبت سازی
Node ORM های زیادی وجود دارد، از جمله Bookshelf.js محبوب و TypeORM.
بنابراین، چرا و چه زمانی Sequelize را انتخاب کنیم؟
اولاً، برای مدت طولانی وجود داشته است – 2011. هزاران ستاره GitHub دارد و توسط هزاران برنامه استفاده می شود. با توجه به سن و محبوبیت آن پایدار است و اسناد زیادی به صورت آنلاین در دسترس است.
علاوه بر بلوغ و ثبات، Sequelize دارای مجموعه ای از ویژگی های بزرگ است که شامل موارد زیر است: پرس و جوها، دامنه ها، روابط، تراکنش ها، پرس و جوهای خام، مهاجرت ها، تکرار خواندن و غیره.
نکته قابل توجه این است که Sequelize مبتنی بر وعده است و مدیریت توابع ناهمزمان و استثناها را آسانتر میکند. همچنین از تمامی گویش های محبوب SQL پشتیبانی می کند: PostgreSQL، MySQL، MariaDB، SQLite و MSSQL.
از سوی دیگر، هیچ پشتیبانی NoSQL وجود ندارد که بتوان آن را در ORM ها (یا Object) دید سند نقشه برداران، در این مورد) مانند مانگوس. در واقع، تصمیم گیری برای انتخاب کدام ORM به طور عمده بستگی دارد روی الزامات پروژه ای که در حال کار آن هستید روی.
نصب Sequelize
توجه داشته باشید: اگر می خواهید همراه با کد دنبال کنید، می توانید آن را پیدا کنید اینجا روی GitHub.
بیایید یک برنامه Node اسکلت بسازیم و Sequelize را نصب کنیم. ابتدا، بیایید یک دایرکتوری برای پروژه خود ایجاد کنیم، آن را وارد کنیم و یک پروژه با تنظیمات پیش فرض ایجاد کنیم:
$ mkdir notes-app
$ cd notes-app
$ npm init -y
در مرحله بعد، فایل برنامه را با یک سرور و روتر اصلی Express ایجاد می کنیم. بیایید آن را صدا کنیم index.js
برای مطابقت با نام فایل پیش فرض از npm init
:
در مرحله بعد، برای ایجاد آسان یک وب سرور، Express را نصب می کنیم:
$ npm install --save express
و با نصب آن، بیایید سرور را راه اندازی کنیم:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => res.send('Notes App'));
app.listen(port, () => console.log(`notes-app listening روی port ${port}!`));
در نهایت، میتوانیم ادامه دهیم و Sequelize و پایگاه داده انتخابی خود را از طریق آن نصب کنیم npm
:
$ npm install --save sequelize
$ npm install --save sqlite3
فرقی نمی کند که کدام پایگاه داده را به عنوان Sequelize استفاده می کنید، پایگاه داده-اگنوستیک است. روشی که ما از آن استفاده می کنیم، بدون توجه به پایگاه داده اصلی، یکسان است. کار با SQLite3 برای توسعه محلی آسان است و یک انتخاب محبوب برای این اهداف است.
حالا بیایید مقداری کد به آن اضافه کنیم index.js
فایل برای راه اندازی پایگاه داده و بررسی اتصال با استفاده از Sequelize. بسته به روی از کدام پایگاه داده استفاده می کنید، ممکن است لازم باشد گویش دیگری را تعریف کنید:
const Sequelize = require('sequelize');
const sequelize = new Sequelize({
// The `host` parameter is required for other databases
// host: 'localhost'
dialect: 'sqlite',
storage: './database.sqlite'
});
پس از وارد کردن Sequelize، آن را با پارامترهایی که برای اجرا نیاز دارد تنظیم می کنیم. همچنین می توانید پارامترهای بیشتری را در اینجا اضافه کنید، مانند pool
، اگرچه آنچه ما داریم برای شروع کافی است. این dialect
بستگی دارد روی از کدام پایگاه داده استفاده می کنید و storage
به سادگی به فایل پایگاه داده اشاره می کند.
این database.sqlite
فایل به طور خودکار در root سطح پروژه ما
توجه داشته باشید: ارزش بررسی کردن را دارد دنباله دار کردن Docs برای راه اندازی پایگاه داده های مختلف و اطلاعات مورد نیاز برای هر کدام.
اگر از MySQL، Postgres، MariaDB یا MSSQL استفاده میکنید، به جای اینکه هر پارامتر را جداگانه ارسال کنید، میتوانید URI اتصال را نیز ارسال کنید:
const sequelize = new Sequelize('postgres://user:(email protected):5432/dbname');
در نهایت، اجازه دهید اتصال را با اجرای آن تست کنیم .authenticate()
روش. زیر کاپوت، آن را به سادگی اجرا می کند SELECT
پرس و جو کنید و بررسی کنید که آیا پایگاه داده به درستی پاسخ می دهد:
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
با اجرای برنامه، با استقبال مواجه می شویم:
$ node index.js
notes-app listening روی port 3000!
Executing (default): SELECT 1+1 AS result
Connection has been established successfully.
ایجاد یک مدل برای نقشه برداری
قبل از اینکه بتوانیم یک Notes API بسازیم، باید یک جدول یادداشت ایجاد کنیم. برای این کار باید a را تعریف کنیم Note
مدل، که ما آن را به یک ثابت اختصاص می دهیم تا بتوان از آن در سراسر API ما استفاده کرد. در define
تابع نام جدول و فیلدها را مشخص می کنیم. در این مورد یک فیلد متنی برای یادداشت و یک رشته برای برچسب:
مانند پایگاه داده های رابطه ای، قبل از ساختن یک API، ابتدا باید جداول کافی ایجاد کنیم. از آنجایی که می خواهیم از ایجاد آن با دست با استفاده از SQL اجتناب کنیم، a را تعریف می کنیم Model
کلاس و سپس Sequelize آن را در یک جدول ترسیم کند.
این را می توان با گسترش دادن انجام داد Sequelize.Model
کلاس و اجرای .init()
تابع، عبور پارامترها، یا با تعریف a const
و به آن مقدار بازگشتی the را نسبت می دهیم .define()
روش از Sequelize.
دومی مختصرتر است، بنابراین ما با آن یکی میرویم:
const Note = sequelize.define('notes', { note: Sequelize.TEXT, tag: Sequelize.STRING });
نگاشت مدل به پایگاه داده
اکنون که ما یک Note
مدلی که می توانیم ایجاد کنیم notes
جدول در پایگاه داده در یک برنامه تولید، ما معمولاً تغییرات پایگاه داده را از طریق انجام می دهیم مهاجرت ها به طوری که تغییرات در کنترل منبع ردیابی می شوند.
اگرچه، برای مختصر نگه داشتن موارد، از آن استفاده خواهیم کرد .sync()
روش. چه .sync()
انجام می دهد ساده است – همه مدل های تعریف شده را با پایگاه داده همگام می کند:
sequelize.sync({ force: true })
.then(() => {
console.log(`Database & tables created!`);
});
در اینجا، ما از آن استفاده کرده ایم force
پرچم گذاری کنید و روی آن تنظیم کنید true
. اگر جدولی از قبل وجود داشته باشد، روش وجود دارد DROP
آن و CREATE
یک دانه جدید. اگر وجود نداشته باشد، فقط یک جدول ایجاد می شود.
در نهایت، اجازه دهید چند یادداشت نمونه ایجاد کنیم که سپس در پایگاه داده باقی میمانیم:
sequelize.sync({ force: true })
.then(() => {
console.log(`Database & tables created!`);
Note.bulkCreate((
{ note: 'pick up some bread after work', tag: 'shopping' },
{ note: 'remember to write up meeting notes', tag: 'work' },
{ note: 'learn how to use node orm', tag: 'work' }
)).then(function() {
return Note.findAll();
}).then(function(notes) {
console.log(notes);
});
});
با اجرای سرور، یادداشتهای ما در آن چاپ میشوند consoleو همچنین عملیات SQL انجام شده توسط Sequelize. بیایید به پایگاه داده متصل شویم تا بررسی کنیم که رکوردها واقعاً به درستی اضافه شده اند:
$ sqlite3 database.sqlite
sqlite> select * from notes;
1|pick up some bread after work|shopping|2020-02-21 18:24:19.402 +00:00|2020-02-21 18:24:19.402 +00:00
2|remember to write up meeting notes|work|2020-02-21 18:24:19.402 +00:00|2020-02-21 18:24:19.402 +00:00
3|learn how to use node orm|work|2020-02-21 18:24:19.402 +00:00|2020-02-21 18:24:19.402 +00:00
sqlite> .exit
با وجود پایگاه داده و ایجاد جدول(های) ما، بیایید جلو برویم و عملکرد اصلی CRUD را پیاده سازی کنیم.
موجودیت های خواندنی
مدل ما، Note
، اکنون متدهای داخلی دارد که به ما در انجام عملیات کمک می کند روی رکوردهای ماندگار در پایگاه داده
همه نهادها را بخوانید
برای مثال، میتوانیم تمام رکوردهای آن کلاس را که با استفاده از عبارت ذخیره شده است، بخوانیم .findAll()
روش. بیایید یک نقطه پایانی ساده بسازیم که به همه موجودیتهای پایدار خدمات میدهد:
app.get('/notes', function(req, res) {
Note.findAll().then(notes => res.json(notes));
});
این .findAll()
متد آرایهای از یادداشتها را برمیگرداند که میتوانیم از آنها برای رندر کردن بدنه پاسخ استفاده کنیم res.json
.
بیایید نقطه پایانی را از طریق آزمایش کنیم curl
:
$ curl http://localhost:3000/notes
({"id":1,"note":"pick up some bread after work","tag":"shopping","createdAt":"2020-02-27T17:02:10.881Z","updatedAt":"2020-02-27T17:02:10.881Z"},{"id":2,"note":"remember to write up meeting notes","tag":"work","createdAt":"2020-02-27T17:02:10.881Z","updatedAt":"2020-02-27T17:02:10.881Z"},{"id":3,"note":"learn how to use node orm","tag":"work","createdAt":"2020-02-27T17:02:10.881Z","updatedAt":"2020-02-27T17:02:10.881Z"})
همانطور که می بینید، تمام ورودی های پایگاه داده ما به ما بازگردانده شد، اما به صورت JSON.
اگرچه، اگر به دنبال اضافه کردن عملکردهای بیشتر هستیم، عملیات پرس و جو مانند SELECT
، WHERE
، AND
، OR
، و LIMIT
توسط این روش پشتیبانی می شود.
لیست کاملی از روش های پرس و جو پشتیبانی شده را می توان یافت روی را دنباله دار کردن Docs page.
Entities WHERE را بخوانید
با در نظر گرفتن این موضوع، بیایید یک نقطه پایانی ایجاد کنیم که یک یادداشت واحد و خاص را ارائه می دهد:
app.get('/notes/:id', function(req, res) {
Note.findAll({ where: { id: req.params.id } }).then(notes => res.json(notes));
});
نقاط پایانی یک را می پذیرد id
پارامتر، برای جستجوی یادداشت از طریق WHERE
عبارت. بیایید آن را از طریق تست کنیم curl
:
$ curl http://localhost:3000/notes/2
({"id":2,"note":"remember to write up meeting notes","tag":"work","createdAt":"2020-02-27T17:03:17.592Z","updatedAt":"2020-02-27T17:03:17.592Z"})
توجه داشته باشید: از آنجایی که این مسیر از یک پارامتر wildcard استفاده می کند، :id
، مطابقت خواهد داشت هر رشته ای که بعد از آن می آید /notes/
. به همین دلیل، این مسیر باید در پایان فایل index.js شما. این اجازه می دهد تا مسیرهای دیگر، مانند /notes/search
، برای رسیدگی به یک درخواست قبل از /notes/:id
آن را برمی دارد. در غیر این صورت search
کلمه کلیدی در مسیر URL مانند یک شناسه رفتار می شود.
Entities WHERE AND را بخوانید
برای پرس و جوهای خاص تر، بیایید با استفاده از هر دو نقطه پایانی ایجاد کنیم WHERE
و AND
بیانیه:
app.get('/notes/search', function(req, res) {
Note.findAll({ where: { note: req.query.note, tag: req.query.tag } }).then(notes => res.json(notes));
});
در اینجا، ما به دنبال یادداشت هایی هستیم که با هر دو مورد مطابقت دارند note
و tag
توسط پارامترها مشخص شده است. دوباره، بیایید آن را از طریق تست کنیم curl
:
$ curl "http://localhost:3000/notes/search؟note=pick%20up%20some%20bread%20after%20work&tag=shopping"
({"id":1,"note":"pick up some bread after work","tag":"shopping","createdAt":"2020-02-27T17:09:53.964Z","updatedAt":"2020-02-27T17:09:53.964Z"})
Entities OR را بخوانید
اگر سعی می کنیم کمی مبهم تر باشیم، می توانیم از آن استفاده کنیم OR
بیانیه و جستجوی یادداشت هایی که مطابقت دارند هر از پارامترهای داده شده تغییر دادن /notes/search
مسیر به:
const Op = Sequelize.Op;
app.get('/notes/search', function(req, res) {
Note.findAll({
where: {
tag: {
(Op.or): ().concat(req.query.tag)
}
}
}).then(notes => res.json(notes));
});
در اینجا ما استفاده می کنیم Sequelize.Op
برای اجرای یک OR
پرس و جو. Sequelize چندین عملگر را برای انتخاب از جمله فراهم می کند Op.or
، Op.and
، Op.eq
، Op.ne
، Op.is
، Op.not
و غیره. اینها عمدتاً برای ایجاد عملیات پیچیده تر، مانند پرس و جو با یک رشته regex استفاده می شوند.
توجه داشته باشید که ما استفاده می کنیم req.query.tag
به عنوان استدلال به .findAll()
. Sequelize در اینجا یک آرایه را انتظار دارد، بنابراین ما را مجبور می کنیم tag
آرایه ای با استفاده از ().concat()
. در آزمون زیر، چندین آرگومان را در URL درخواست خود ارسال خواهیم کرد:
$ curl "http://localhost:3000/notes/search؟tag=shopping&tag=work"
({"id":1,"note":"pick up some bread after work","tag":"shopping","createdAt":"2020-02-27T17:11:27.518Z","updatedAt":"2020-02-27T17:11:27.518Z"},{"id":2,"note":"remember to write up meeting notes","tag":"work","createdAt":"2020-02-27T17:11:27.518Z","updatedAt":"2020-02-27T17:11:27.518Z"},{"id":3,"note":"learn how to use node orm","tag":"work","createdAt":"2020-02-27T17:11:27.518Z","updatedAt":"2020-02-27T17:11:27.518Z"})
هنگامی که یک پارامتر پرس و جو را چندین بار مانند این ارسال می کنید، به عنوان یک آرایه در نشان داده می شود req.query
هدف – شی. بنابراین در مثال بالا، req.query.tag
است ('shopping', 'work')
.
Entities LIMIT را بخوانید
آخرین چیزی که در این بخش به آن خواهیم پرداخت این است LIMIT
. بیایید بگوییم که میخواستیم کوئری قبلی را تغییر دهیم تا حداکثر دو نتیجه را برگردانیم. ما این کار را با اضافه کردن limit
پارامتر و تخصیص یک عدد صحیح مثبت به آن:
const Op = Sequelize.Op;
app.get('/notes/search', function(req, res) {
Note.findAll({
limit: 2,
where: {
tag: {
(Op.or): ().concat(req.query.tag)
}
}
}).then(notes => res.json(notes));
});
شما می توانید لیست کاملی از توابع پرس و جو را در آدرس مشاهده کنید اسناد را دنباله دار کنید.
درج موجودیت ها
درج موجودیت ها بسیار ساده تر است زیرا واقعاً دو راه برای انجام این عملیات وجود ندارد.
بیایید یک نقطه پایانی جدید برای اضافه کردن یادداشت ها اضافه کنیم:
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/notes', function(req, res) {
Note.create({ note: req.body.note, tag: req.body.tag }).then(function(note) {
res.json(note);
});
});
این body-parser
ماژول برای پذیرش و تجزیه پارامترهای JSON توسط نقطه پایانی مورد نیاز است. شما نیازی به نصب صریح ندارید body-parser
بسته به دلیل اینکه قبلاً با Express همراه شده است.
در داخل مسیری که از آن استفاده می کنیم .create()
روش برای درج یادداشت در پایگاه داده، بر اساس روی پارامترهای تصویب شده
ما می توانیم آن را با دیگری آزمایش کنیم curl
درخواست:
$ curl -d '{"note":"go the gym","tag":"health"}' -H "Content-Type: application/json" -X POST http://localhost:3000/notes
{"id":4,"note":"go the gym","tag":"health","updatedAt":"2020-02-27T17:13:42.281Z","createdAt":"2020-02-27T17:13:42.281Z"}
اجرای این درخواست منجر به ایجاد یک یادداشت در پایگاه داده ما می شود و شی پایگاه داده جدید را به ما برمی گرداند.
به روز رسانی نهادها
گاهی اوقات، ما می خواهیم موجودیت های موجود را به روز کنیم. برای انجام این کار، ما تکیه می کنیم روی را .update()
روش روی نتیجه از .findByPk()
روش:
app.put('/notes/:id', function(req, res) {
Note.findByPk(req.params.id).then(function(note) {
note.update({
note: req.body.note,
tag: req.body.tag
}).then((note) => {
res.json(note);
});
});
});
این .findByPk()
متد نیز یک متد ارثی در کلاس مدل ما است. یک موجودیت با کلید اصلی داده شده را جستجو می کند. اساسا، بازگرداندن واحدهای منفرد با شناسه آنها با استفاده از این روش آسانتر از نوشتن a است SELECT WHERE
پرس و جو.
با توجه به موجودیت بازگشتی، ما آن را اجرا می کنیم .update()
روشی برای قرار دادن مقادیر جدید در واقع. بیایید این را از طریق تأیید کنیم curl
:
$ curl -X PUT -H "Content-Type: application/json" -d '{"note":"pick up some milk after work","tag":"shopping"}' http://localhost:3000/notes/1
{"id":1,"note":"pick up some milk after work","tag":"shopping","createdAt":"2020-02-27T17:14:55.621Z","updatedAt":"2020-02-27T17:14:58.230Z"}
با ارسال این درخواست اولین یادداشت با محتوای جدید به روز می شود و شی به روز شده را برمی گرداند:
حذف نهادها
و در نهایت، زمانی که میخواهیم رکوردها را از پایگاه داده خود حذف کنیم، از آن استفاده میکنیم .destroy()
روش روی نتیجه از .findByPk()
روش:
app.delete('/notes/:id', function(req, res) {
Note.findByPk(req.params.id).then(function(note) {
note.destroy();
}).then((note) => {
res.sendStatus(200);
});
});
مسیر برای .delete()
شبیه به .update()
. ما استفاده می کنیم .findByPk()
برای پیدا کردن یک یادداشت خاص با شناسه سپس .destroy()
متد یادداشت را از پایگاه داده حذف می کند.
در نهایت، الف 200 OK
پاسخ به مشتری برگردانده می شود.
نتیجه
نگاشت رابطه ای شی (ORM) تکنیکی است که اشیاء نرم افزار را به جداول پایگاه داده نگاشت می کند. Sequelize یک ابزار ORM محبوب و پایدار است که در کنار Node.js استفاده می شود. در این مقاله، در مورد اینکه ORM ها چیست، چگونه کار می کنند و مزایای استفاده از آنها نسبت به نوشتن پرس و جوهای خام چیست، بحث کرده ایم.
با این دانش، ما اقدام به نوشتن یک برنامه ساده Node.js/Express کردیم که از Sequelize برای تداوم یک برنامه استفاده می کند. Note
مدل به پایگاه داده با استفاده از روش های ارثی، ما سپس عملیات CRUD را انجام دادیم روی پایگاه داده.
با خیال راحت کد را بررسی کنید روی GitHub اگر مشکلی داشتید این آموزش را دنبال کنید.
(برچسبها برای ترجمه)# جاوا اسکریپت
منتشر شده در 1403-01-21 15:37:02