از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
آموزش SQLite با Node.js در این آموزش روش استفاده از SQLite را در ترکیب با جاوا اسکریپت در محیط Node.js با کمک درایور sqlite3 Node.js نشان خواهم داد. برای کسانی که با SQLite آشنایی ندارند، این یک پایگاه داده ارتباطی تک فایلی ساده است که در بین دستگاه های هوشمند بسیار محبوب است.
سرفصلهای مطلب
در این آموزش روش استفاده از SQLite را در ترکیب با جاوا اسکریپت در محیط Node.js با کمک درایور sqlite3 Node.js نشان خواهم داد. برای کسانی که آشنایی ندارند SQLite، این یک پایگاه داده رابطه ای تک فایل ساده است که در بین دستگاه های هوشمند، سیستم های جاسازی شده و حتی برنامه های وب کوچک بسیار محبوب است.
راه اندازی و نصب
من با ایجاد یک بسته جدید npm با استفاده از آن شروع خواهم کرد npm init
داخل یک دایرکتوری خالی به نام node-sqlite-tutorial
.
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.
See `npm help json` for definitive documentation روی these fields
and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (app) node-sqlite
version: (0.0.0) 0.1.0
description: Code for tutorial blog روی node and sqlite
entry point: (index.js) main.js
test command:
git repository:
keywords:
author: Adam McQuistan
license: (BSD) MIT
About to write to /node-sqlite/app/package.json:
{
"name": "node-sqlite",
"version": "0.1.0",
"description": "Code for tutorial blog روی node and sqlite",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": "",
"author": "Adam McQuistan",
"license": "MIT"
}
Is this ok? (yes)
بعد باید نصب کنم sqlite3 بسته از طریق npm مانند:
$ npm install --save sqlite3
علاوه بر sqlite3 قرار است نصب کنم پرنده ابی تا بتوانم از عملکرد آشنای وعده در برنامه نویسی پایگاه داده خود استفاده کنم.
$ npm install --save bluebird
اکنون یک فایل خالی درست در کنار آن ایجاد می کنم package.json
فایل فراخوانی شد database.sqlite3
که SQLite داده ها را در آن ذخیره می کند.
طراحی پایگاه داده
مانند تقریباً هر مقاله دیگری من از یک برنامه کاربردی برای کمک به توصیف برخی از جنبه های مهم برنامه نویسی پایگاه داده با Node.js و SQLite استفاده خواهم کرد. برای این مقاله، من با این فرض پیش می روم که لایه دسترسی به داده ها را برای برنامه ردیابی پروژه و کار ایجاد می کنم. قوانین اساسی کسب و کار برای لایه دسترسی به داده این برنامه به شرح زیر است:
- برنامه دارای پروژه هایی است
- هر پروژه می تواند یک یا چند کار برای تکمیل داشته باشد
با قوانین تجاری بیان شده، می توانم آن اطلاعات را بگیرم و شروع به طراحی جداول لازم و فیلدهای آنها کنم. واضح است که به الف نیاز خواهم داشت پروژه ها جدول و همچنین یک وظایف جدول. برای بقیه، فقط از کمی شهود استفاده میکنم، برخی از دادههای آزمایشی را میسازم، و با آن رول میکنم (ویژگی کاری رایج برای اکثر توسعهدهندگان).
جدول پروژه ها
شناسه | نام |
---|---|
1 | رایت Node.js – آموزش SQLite |
جدول وظایف
شناسه | نام | شرح | تکمیل شده است | شناسه پروژه |
---|---|---|---|---|
1 | طرح کلی | نمای کلی سطح بالا از بخش ها | 1 | 1 |
2 | نوشتن | محتوای مقاله و نمونه کد بنویسید | 0 | 1 |
خوب، اکنون که می دانم چه چیزی را باید ایجاد کنم، اکنون می توانم آن را به کد ترجمه کنم.
ایجاد پایگاه داده
برای شروع باید یک main.js
فایل همراه با الف dao.js
(یا شیء دسترسی به داده) فایل در همان دایرکتوری با package.json
فایل.
داخل dao.js
، برای sqlite3 و Bluebird’s import اضافه می کنم Promise
اشیاء. پس از آن من یک کلاس دسترسی به داده به نام داربست خواهم ساخت AppDAO
که یک اتصال به پایگاه داده در داخل سازنده ایجاد می کند و آن را به یک فیلد عضو به نام اختصاص می دهد db
.
// dao.js
const sqlite3 = require('sqlite3')
const Promise = require('bluebird')
class AppDAO {
constructor(dbFilePath) {
this.db = new sqlite3.Database(dbFilePath, (err) => {
if (err) {
console.log('Could not connect to database', err)
} else {
console.log('Connected to database')
}
})
}
}
module.exports = AppDAO
اتصال بسیار مستقیم است. شما فقط sqlite3 را نمونه برداری می کنید Database
سازنده کلاس با ارسال مسیر به فایل پایگاه داده SQLite که می خواهید با آن ارتباط برقرار کنید و به صورت اختیاری خطاهایی را که ممکن است رخ دهد بررسی کنید. همانطور که در بالا ذکر شد، من این شی اتصال را در فیلدی به نام ذخیره می کنم db
روی را AppDAO
کلاس
من با توضیح روش استفاده از شی اتصال برای ارسال پرس و جو به پایگاه داده پیشرفت خواهم کرد. بسته sqlite3 Node.js تعدادی روش مختلف برای اجرای کوئری ها ارائه می دهد، اما روش هایی که من روی آنها تمرکز خواهم کرد. روی در این آموزش عبارتند از:
run
: برای ایجاد یا تغییر جداول و درج یا به روز رسانی داده های جدول استفاده می شودget
: یک ردیف از داده ها را از یک یا چند جدول انتخاب کنیدall
: چندین ردیف داده را از یک یا چند جدول انتخاب کنید
برای شروع من می خواهم به کشف run
روش. نحو کلی آن به شکل زیر است:
db.run('SOME SQL QUERY', (param1, param2), (err) => {
if (err) {
console.log('ERROR!', err)
}
})
پارامتر اول به run(...)
یک رشته از SQL است که باید اجرا شود و تنها پارامتر مورد نیاز است. دومین آرایه اختیاری از پارامترها است که کتابخانه sqlite3 آن را انجام خواهد داد swap برای هر “؟” متغیرهایی در پرس و جو (این را در اندکی نشان خواهم داد). آخرین یک تابع تماس خطا است.
همانطور که ممکن است مشکوک باشید من از آن استفاده خواهم کرد run(...)
برای ایجاد و به روز رسانی پروژه ها و وظایف من. با این حال، من در واقع قصد دارم آن را در نسخه خودم از a بپیچم run
روش روی را AppDAO
کلاس چون می خواهم آن را در یک کپسوله کنم bluebird
Promise
برای اینکه چیزها به طور صریح ناهمزمان و مبتنی بر قول باشند مانند این:
// dao.js
const sqlite3 = require('sqlite3')
const Promise = require('bluebird')
class AppDAO {
// omitting constructor code
run(sql, params = ()) {
return new Promise((resolve, reject) => {
this.db.run(sql, params, function (err) {
if (err) {
console.log('Error running sql ' + sql)
console.log(err)
reject(err)
} else {
resolve({ id: this.lastID })
}
})
})
}
}
با سفارش من AppDAO.run(...)
روشی که اکنون می توانم از آن برای ایجاد جداول محصولات و وظایف استفاده کنم.
برای شروع، من دو فایل دیگر به پروژه خود به نام های project_repository.js و task_repository.js اضافه می کنم. در داخل project_repository.js کلاسی به نام تعریف می کنم ProjectRepository
که سازنده ای دارد که نمونه ای از را می پذیرد AppDAO
شیء و الف createTable
روشی که برخی از DDL (زبان تعریف داده) SQL را اجرا می کند مانند:
// project_repository.js
class ProjectRepository {
constructor(dao) {
this.dao = dao
}
createTable() {
const sql = `
CREATE TABLE IF NOT EXISTS projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT)`
return this.dao.run(sql)
}
}
module.exports = ProjectRepository;
سپس من اساساً همان کار را دوباره انجام می دهم، اما، این بار در فایل task_repository.js.
// task_repository.js
class TaskRepository {
constructor(dao) {
this.dao = dao
}
createTable() {
const sql = `
CREATE TABLE IF NOT EXISTS tasks (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
description TEXT,
isComplete INTEGER DEFAULT 0,
projectId INTEGER,
CONSTRAINT tasks_fk_projectId FOREIGN KEY (projectId)
REFERENCES projects(id) روی UPDATE CASCADE روی DELETE CASCADE)`
return this.dao.run(sql)
}
}
module.exports = TaskRepository;
DDL SQL برای ایجاد جداول کامل شده است، بنابراین من حرکت می کنم روی به روش هایی برای درج داده ها در جداول.
درج داده ها
در ProjectRepository
کلاس باید a اضافه کنم create
متدی که نام پروژه را برای ایجاد و اجرای دستور INSERT مناسب با استفاده از AppDAO.run(...)
روش. توجه کنید که من چگونه از “؟” استفاده کرده ام برای نشان دادن مقدار نام پروژه و سپس قرار دادن name
پارامتر در آرگومان آرایه پارامترهای اختیاری به run(...)
روش. این به عنوان یک عبارت پرس و جو پارامتری شناخته می شود که ورودی ها را برای به حداقل رساندن خطرات تزریق SQL پاک می کند.
// project_repository.js
class ProjectRepository {
// omitting other methods
create(name) {
return this.dao.run(
'INSERT INTO projects (name) VALUES (?)',
(name))
}
}
module.exports = ProjectRepository;
یک روش ایجاد مشابه برای TaskRepository
کلاس
// task_repository.js
class TaskRepository {
// omitting other methods
create(name, description, isComplete, projectId) {
return this.dao.run(
`INSERT INTO tasks (name, description, isComplete, projectId)
VALUES (?, ?, ?, ?)`,
(name, description, isComplete, projectId))
}
}
module.exports = TaskRepository;
اکنون که توانایی درج دادهها در پایگاه داده را دارم، میخواهم عملکردی را برای بهروزرسانی آن اضافه کنم.
به روز رسانی داده ها
در ProjectRepository
کلاس را اضافه خواهم کرد update
روشی که الف project
شی و تمام فیلدهای رکورد پایگاه داده آن پروژه را دوباره با استفاده از آن به روز می کند AppDAO.run(...)
روش، مانند:
// project_repository.js
class ProjectRepository {
// omitting other methods
update(project) {
const { id, name } = project
return this.dao.run(
`UPDATE projects SET name = ? WHERE id = ?`,
(name, id)
)
}
}
module.exports = ProjectRepository;
مرحله بعدی اضافه کردن روش به روز رسانی مربوطه است TaskRepository
کلاس
// task_repository.js
class TaskRepository {
// omitting other methods
update(task) {
const { id, name, description, isComplete, projectId } = task
return this.dao.run(
`UPDATE tasks
SET name = ?,
description = ?,
isComplete = ?,
projectId = ?
WHERE id = ?`,
(name, description, isComplete, projectId, id)
)
}
}
module.exports = TaskRepository;
حذف داده ها
آخرین عملکرد جهشی برای پیاده سازی، ارائه توانایی حذف رکوردها از پایگاه داده است. برای این من دوباره استفاده خواهم کرد AppDAO.run(...)
روش در ارتباط با جدید delete
روش برای هر دو ProjectRepository
و TaskRepository
کلاس ها.
برای ProjectRepository
به نظر می رسد این است:
// project_repository.js
class ProjectRepository {
// omitting other methods
delete(id) {
return this.dao.run(
`DELETE FROM projects WHERE id = ?`,
(id)
)
}
}
module.exports = ProjectRepository;
و برای TaskRepository
به نظر می رسد این است:
// task_repository.js
class TaskRepository {
// omitting other methods
delete(id) {
return this.dao.run(
`DELETE FROM tasks WHERE id = ?`,
(id)
)
}
}
module.exports = TaskRepository;
بسیار خوب، این همه راه هایی را که من از آن استفاده خواهم کرد را کامل می کند run
روش. در ادامه به معرفی دو مرتبط دیگر می پردازم get
و all
روش های بسته sqlite3 Node.js.
خواندن داده ها
در این بخش قصد دارم به روش استفاده از آن بپردازم get
و all
روش های کتابخانه sqlite3 Node.js. همانطور که قبلا ذکر شد، get
برای بازیابی یک ردیف داده در حالی که استفاده می شود all
برای پرس و جوی بسیاری از ردیف های داده استفاده می شود.
نحو پایه برای استفاده get
به نظر می رسد این است:
db.get('SELECT ...', (param1, param2), (err, result) => {
if (err) {
console.log(err)
} else {
// do something with result
}
})
جایی که db
یک شی اتصال sqlite3 است. متوجه خواهید شد که نحو اساساً مشابه است run
روش با این تفاوت که فراخوان دارای یک پارامتر اضافی است که با فرض اینکه هیچ خطایی وجود نداشته باشد، شی نتیجه پرس و جو را نگه می دارد.
نحو پایه برای all
اساساً دوباره یکسان است، به جز اینکه پارامتر دوم به فراخوان آرایه ای از نتایج برگردانده شده توسط پرس و جو است، مانند:
db.all('SELECT ...', (param1, param2), (err, results) => {
if (err) {
console.log(err)
} else {
// do something with results
}
})
درست مثل کاری که با sqlite3 انجام دادم run
روشی که من قصد دارم آن را پیاده سازی کنم get
و all
روش های استفاده از bluebird
Promise
در داخل AppDAO
کلاس مطابق شکل زیر:
// dao.js
const sqlite3 = require('sqlite3').verbose()
const Promise = require('bluebird')
class AppDAO {
// omitting other methods
get(sql, params = ()) {
return new Promise((resolve, reject) => {
this.db.get(sql, params, (err, result) => {
if (err) {
console.log('Error running sql: ' + sql)
console.log(err)
reject(err)
} else {
resolve(result)
}
})
})
}
all(sql, params = ()) {
return new Promise((resolve, reject) => {
this.db.all(sql, params, (err, rows) => {
if (err) {
console.log('Error running sql: ' + sql)
console.log(err)
reject(err)
} else {
resolve(rows)
}
})
})
}
}
اکنون می توانم از این روش ها در سایت استفاده کنم ProjectRepository
و TaskRepository
کلاس هایی برای بازیابی داده ها از پایگاه داده SQLite.
برای شروع اضافه می کنم getById
روش هایی برای هر کلاس برای انتخاب رکوردهای خود بر اساس id.
که در ProjectRepository
این را اضافه می کنم:
// project_repository.js
class ProjectRepository {
// omitting other methods
getById(id) {
return this.dao.get(
`SELECT * FROM projects WHERE id = ?`,
(id))
}
}
module.exports = ProjectRepository;
و در TaskRepository
به طور مشابه:
// task_repository.js
class TaskRepository {
// omitting other methods
getById(id) {
return this.dao.get(
`SELECT * FROM tasks WHERE id = ?`,
(id))
}
}
module.exports = TaskRepository;
برای نشان دادن AppDAO.all(...)
روش من توانایی انتخاب همه پروژه ها و همچنین تمام وظایف برای یک پروژه معین را اضافه می کنم.
کد SELECT همه پروژه ها به شکل زیر است:
// project_repository.js
class ProjectRepository {
// omitting other methods
getAll() {
return this.dao.all(`SELECT * FROM projects`)
}
}
module.exports = ProjectRepository;
سپس برای انتخاب تمام وظایف یک پروژه از روشی به نام استفاده می کنم getTasks(projectId)
که انتظار دارد شناسه پروژه ای که وظایف آن را می خواهید داشته باشد.
// project_repository.js
class ProjectRepository {
// omitting other methods
getTasks(projectId) {
return this.dao.all(
`SELECT * FROM tasks WHERE projectId = ?`,
(projectId))
}
}
module.exports = ProjectRepository;
استفاده از کد دسترسی به داده ها
تا کنون من اساساً یک کتابخانه دسترسی به داده برای این پروژه ساختگی و برنامه ردیابی کار ایجاد کرده ام. کاری که اکنون میخواهم انجام دهم این است که از آن برای بارگذاری دادههای آزمایشی که در جداول موجود در جدول نمایش داده شده است استفاده کنم طراحی پایگاه داده بخش.
در main.js
فایل، من می خواهم به جلو و در AppDAO
، ProjectRepository
، و TaskRepository
کلاس ها از طریق require
. سپس از آنها برای ایجاد جداول، پر کردن آنها با داده ها، بازیابی داده ها از پایگاه داده و نمایش آنها در console.
// main.js
const Promise = require('bluebird')
const AppDAO = require('./dao')
const ProjectRepository = require('./project_repository')
const TaskRepository = require('./task_repository')
function main() {
const dao = new AppDAO('./database.sqlite3')
const blogProjectData = { name: 'Write Node.js - SQLite Tutorial' }
const projectRepo = new ProjectRepository(dao)
const taskRepo = new TaskRepository(dao)
let projectId
projectRepo.createTable()
.then(() => taskRepo.createTable())
.then(() => projectRepo.create(blogProjectData.name))
.then((data) => {
projectId = data.id
const tasks = (
{
name: 'Outline',
description: 'High level overview of sections',
isComplete: 1,
projectId
},
{
name: 'Write',
description: 'Write article contents and code examples',
isComplete: 0,
projectId
}
)
return Promise.all(tasks.map((task) => {
const { name, description, isComplete, projectId } = task
return taskRepo.create(name, description, isComplete, projectId)
}))
})
.then(() => projectRepo.getById(projectId))
.then((project) => {
console.log(`\nRetreived project from database`)
console.log(`project id = ${project.id}`)
console.log(`project name = ${project.name}`)
return taskRepo.getTasks(project.id)
})
.then((tasks) => {
console.log('\nRetrieved project tasks from database')
return new Promise((resolve, reject) => {
tasks.forEach((task) => {
console.log(`task id = ${task.id}`)
console.log(`task name = ${task.name}`)
console.log(`task description = ${task.description}`)
console.log(`task isComplete = ${task.isComplete}`)
console.log(`task projectId = ${task.projectId}`)
})
})
resolve('success')
})
.catch((err) => {
console.log('Error: ')
console.log(JSON.stringify(err))
})
}
main()
با استفاده اجرا کنید node
مثل این:
$ node main.js
و خروجی را مطابق شکل زیر خواهید دید.
Connected to database
Retrieved project from database
project id = 1
project name = 1
Retrieved project tasks from database
task id = 1
task name = Outline
task description = High level overview of sections
task isComplete = 1
task projectId = 1
task id = 2
task name = Write
task description = Write article contents and code examples
task isComplete = 0
task projectId = 1
نتیجه
در این آموزش اصول اولیه API بسته Node.js sqlite3 را بررسی کردهام و نشان دادهام که چگونه میتوانید آن عملکرد را در جاوا اسکریپت شی گرا با تمرکز قرار دهید. روی اجرای ناهمزمان مبتنی بر وعده
مثل همیشه از شما برای خواندن و استقبال از نظرات و انتقادات زیر تشکر می کنم.
(برچسبها برای ترجمه)# جاوا اسکریپت
منتشر شده در 1403-01-26 15:29:04