ЗВІТ З ЛАБОРАТОРНОЇ РОБОТИ № 2
Тема: Створення бази даних у MySQL. Підключення Node.js до MySQL. Робота з ORM Sequelize
Виконав: Вересоцький Арсеній Група: ІК-33
1 СТВОРЕННЯ БАЗИ ДАНИХ ТА ВИКОНАННЯ SQL-ЗАПИТІВ
1.1 Проєктування бази даних
Для системи “Library of Things” (Бібліотека Речей) було спроєктовано базу даних library_of_things_db. На даному етапі створено дві основні таблиці, які пов’язані відношенням One-to-Many (Один-до-багатьох):
- users (Користувачі) — власники речей.
- items (Речі) — предмети, які користувачі здають в оренду.
1.2 Виконання базових SQL-запитів
Для перевірки роботи MySQL сервера було виконано наступні DDL та DML запити безпосередньо в СУБД (наприклад, через DBeaver).
Створення бази даних та таблиць:
CREATE DATABASE library_of_things_db;
USE library_of_things_db;
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE items (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
userId INT,
createdAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (userId) REFERENCES users(id) ON DELETE CASCADE
); CRUD операції (INSERT, SELECT, UPDATE, DELETE):
-- INSERT: Додавання користувачів та речей
INSERT INTO users (name, email) VALUES ('Арсеній Вересоцький', 'arseniy@gmail.com');
INSERT INTO users (name, email) VALUES ('Іван Франко', 'ivan@lot.ua');
INSERT INTO items (title, description, userId)
VALUES ('Дриль ударний', 'Потужний дриль для домашніх робіт', 1);
INSERT INTO items (title, description, userId)
VALUES ('Намет 2-місний', 'Легкий туристичний намет', 1);
-- SELECT: Отримання всіх речей з інформацією про власника (JOIN)
SELECT items.title, items.description, users.name as owner
FROM items
JOIN users ON items.userId = users.id;
-- UPDATE: Оновлення опису речі
UPDATE items SET description = 'Оновлений опис: Намет туристичний (синій)' WHERE id = 2;
-- DELETE: Видалення запису
DELETE FROM items WHERE id = 2; 
2 ПІДКЛЮЧЕННЯ NODE.JS ДО MYSQL (ДРАЙВЕР MYSQL2)
Наступним кроком було підключення створеного у ЛР №1 Node.js проєкту до бази даних MySQL. Для цього встановлено пакет mysql2.
npm install mysql2 Тестове підключення та виконання SQL-запиту через Node.js
// файл raw-db-test.js
const mysql = require('mysql2/promise');
async function testRawConnection() {
try {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'library_of_things_db'
});
console.log('Успішне підключення до MySQL через mysql2!');
// Виконання підготовленого (Prepared) запиту
const [rows] = await connection.execute('SELECT * FROM users WHERE id = ?', [1]);
console.log('Знайдений користувач:', rows);
await connection.end();
} catch (error) {
console.error('Помилка підключення:', error);
}
}
testRawConnection(); 
3 ВИКОРИСТАННЯ ORM SEQUELIZE
Для спрощення роботи з базою даних та заміни “сирих” SQL запитів на роботу з об’єктами JavaScript, у проєкт було інтегровано ORM Sequelize.
npm install sequelize 3.1 Файлова структура проєкту (оновлена)
Було створено нові директорії для конфігурації та моделей:
/lab1-rest-api
├── /config
│ └── database.js # Налаштування підключення Sequelize
├── /models
│ ├── User.js # Модель Користувача
│ └── Item.js # Модель Речі
├── server.js # Головний файл сервера (REST API)
├── package.json
└── README.md 3.2 Налаштування підключення (config/database.js)
const { Sequelize } = require('sequelize');
const sequelize = new Sequelize(
'library_of_things_db', // Назва бази даних
'root', // Користувач
'', // Пароль
{
host: 'localhost',
dialect: 'mysql',
logging: false // Вимикаємо вивід SQL запитів у консоль (опціонально)
}
);
module.exports = sequelize; 3.3 Створення моделей та зв’язків
Модель User (models/User.js):
const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');
const User = sequelize.define('User', {
name: {
type: DataTypes.STRING,
allowNull: false
},
email: {
type: DataTypes.STRING,
allowNull: false,
unique: true
}
});
module.exports = User; Модель Item (models/Item.js):
const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');
const Item = sequelize.define('Item', {
title: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.TEXT,
allowNull: false
}
});
module.exports = Item; Ініціалізація зв’язку One-to-Many у server.js:
У головному файлі сервера моделі було пов’язано між собою. User може мати багато Item, а Item належить одному User.
// Фрагмент server.js
const sequelize = require('./config/database');
const User = require('./models/User');
const Item = require('./models/Item');
// Реалізація зв'язку One-to-Many
User.hasMany(Item, { foreignKey: 'userId' });
Item.belongsTo(User, { foreignKey: 'userId' });
// Синхронізація бази даних
sequelize.sync({ alter: true }) // alter: true оновлює таблиці без їх видалення
.then(() => {
console.log("Таблиці успішно синхронізовані з БД.");
})
.catch(err => console.log("Помилка синхронізації: ", err)); 3.4 Реалізація REST API за допомогою Sequelize
Логіку роботи з масивом у пам’яті (з ЛР №1) було повністю замінено на запити до бази даних через методи Sequelize (findAll, findByPk, create, update, destroy).
Приклад маршрутів (CRUD) для Items у server.js:
// ... (Налаштування express та sequelize)
// GET: Отримати всі речі разом з даними власника
app.get('/items', async (req, res) => {
try {
const items = await Item.findAll({ include: User });
res.json(items);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// POST: Додати нову річ
app.post('/items', async (req, res) => {
try {
const { title, description, userId } = req.body;
const newItem = await Item.create({ title, description, userId });
res.status(201).json(newItem);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// ... (PUT та DELETE реалізовані аналогічно за допомогою Item.update() та Item.destroy()) Для демонстрації роботи створимо нового користувача під іменем Томенко Ярослава та додамо їй бігову доріжку як її річ:

4 ВІДПОВІДІ НА КОНТРОЛЬНІ ПИТАННЯ
- Що таке реляційна база даних?
Реляційна база даних — це тип бази даних, яка зберігає та надає доступ до точок даних, пов’язаних між собою. Дані організовані у вигляді таблиць (рядків та стовпців), а зв’язки між таблицями встановлюються за допомогою первинних (Primary Key) та зовнішніх (Foreign Key) ключів.
- Що таке реляційна база даних?
- Для чого використовується MySQL?
MySQL — це одна з найпопулярніших систем керування реляційними базами даних (RDBMS). Вона використовується для безпечного зберігання, організації, пошуку та модифікації великих обсягів структурованих даних у веб-застосунках.
- Для чого використовується MySQL?
- Що таке ORM?
ORM (Object-Relational Mapping) — це технологія програмування, яка зв’язує бази даних з концепціями об’єктно-орієнтованих мов програмування. Вона створює “віртуальну об’єктну базу даних”, дозволяючи розробнику працювати з таблицями бази даних як з класами, а з рядками таблиць — як з об’єктами, не пишучи чисті SQL-запити.
- Що таке ORM?
- Для чого використовується Sequelize?
Sequelize — це сучасна ORM-бібліотека для Node.js, що підтримує роботу на основі промісів (Promise). Вона використовується для роботи з реляційними базами (MySQL, PostgreSQL, SQLite) напряму через JavaScript, автоматично генеруючи SQL-запити, керуючи міграціями, транзакціями та зв’язками між таблицями.
- Для чого використовується Sequelize?
- Яка різниця між hasMany та belongsTo?
Це методи Sequelize для створення зв’язків.
- hasMany застосовується до “батьківської” моделі (наприклад, User.hasMany(Item) — один користувач має багато речей).
- belongsTo застосовується до “дочірньої” моделі (наприклад, Item.belongsTo(User) — конкретна річ належить одному користувачу). belongsTo автоматично додає зовнішній ключ (Foreign Key) до дочірньої таблиці.
- Яка різниця між hasMany та belongsTo?
- Що таке зв’язок One-to-Many?
One-to-Many (Один-до-багатьох) — це тип відношення у реляційній базі даних, коли один запис у першій таблиці може бути пов’язаний з кількома записами у другій таблиці, але запис із другої таблиці пов’язаний лише з одним записом першої. (Наприклад: один Користувач -> багато Речей на платформі).
- Що таке зв’язок One-to-Many?
- Як виконати SQL-запит з Node.js?
Виконати SQL-запит можна декількома способами:
- Використовуючи “сирі” (raw) драйвери, такі як пакет mysql2 (connection.query(“SELECT * FROM users”)).
- За допомогою ORM (як Sequelize) використовуючи вбудовані методи (User.findAll()).
- За допомогою ORM, але виконуючи сирий запит: sequelize.query(“SELECT * FROM users”).
- Як виконати SQL-запит з Node.js?
ВИСНОВКИ
Під час виконання лабораторної роботи №2 я здобув практичні навички роботи з реляційними базами даних у середовищі Node.js.
Було успішно спроєктовано та створено базу даних MySQL для веб-застосунку “Library of Things” із таблицями users та items. Спочатку я ознайомився з прямим підключенням до СУБД за допомогою драйвера mysql2, що дозволило зрозуміти низькорівневий принцип взаємодії з базою даних через підготовлені SQL-запити.
Головним етапом роботи стало впровадження ORM-бібліотеки Sequelize. Це дозволило абстрагуватися від написання SQL-коду, описати структуру таблиць за допомогою JavaScript-моделей та налаштувати зв’язок “One-to-Many” (hasMany та belongsTo). REST API, розроблене у попередній лабораторній роботі (яке зберігало дані в тимчасовому масиві), було повністю рефакторене: тепер усі CRUD-операції виконуються асинхронно і зберігаються у персистентній базі даних MySQL. Використання Sequelize значно зменшило кількість шаблонного коду, підвищило читабельність та масштабованість бекенду.
