Хочешь уверенно проходить IT-интервью?

Мы понимаем, как сложно подготовиться: стресс, алгоритмы, вопросы, от которых голова идёт кругом. Но с AI тренажёром всё гораздо проще.
💡 Почему Т1 тренажёр — это мастхэв?
- Получишь настоящую обратную связь: где затык, что подтянуть и как стать лучше
- Научишься не только решать задачи, но и объяснять своё решение так, чтобы интервьюер сказал: "Вау!".
- Освоишь все этапы собеседования, от вопросов по алгоритмам до диалога о твоих целях.
Зачем листать миллион туториалов? Просто зайди в Т1 тренажёр, потренируйся и уверенно удиви интервьюеров. Мы не обещаем лёгкой прогулки, но обещаем, что будешь готов!
Реклама. ООО «Смарт Гико», ИНН 7743264341. Erid 2VtzqwP8vqy
Что такое ORM
ORM – (с англ. Object-Relational Mapping, объектно-реляционное отображение) технология в программировании, которая связывает ваши объекты с базой данных, тем самым создавая виртуальную базу данных. К виртуальной базе данных можно обращаться, извлекая или записывая информацию без написания SQL-запросов.
Что такое Sequelize
Sequelize – это Node.js ORM на базе промисов, которая может работать в связке Postgres, MySQL, MariaDB, SQLite, Microsoft SQL Server, Amazon Redshift.
Sequelize может помочь закрыть 90% нужных задач без написания SQL-запросов. Внутри есть поддержка создания, обновления, удаления сущностей. Есть поддержка вложенных сортировок, сложных условий, LEFT JOIN, лимитов, подзапросов, кастомных запросов, а также есть защита от SQL-инъекций и отмена транзакций.
Установка и настройка
Как базу данных мы будем использовать PostgreSQL, поэтому пример интеграции Sequelize в проект будем показывать на ней. С вас готовый Node.js-сервер (можно с express) и развернутая база данных.
Для начала, установим Sequelize командой:
npm install sequelize
После этого устанавливаем «драйверы» для ORM:
npm install pg pg-hstore
Если вы пожелаете использовать MySQL вместо Postgres, то вам надо установить другие пакеты:
npm install --save mysql2
Подробней про это можно почитать тут.
Подключайте базу данных в основном файле проекта (это может быть app.js).
const db = require('./db.js')
db.authenticate()
.catch(error => console.error(error))
const Sequilize = require('sequelize')
module.exports = new Sequilize('proglib', 'postgres', 'secret', {
host: 'localhost',
dialect: 'postgres',
operatorsAliases: 0,
pool: {
max: 5,
min: 0,
acquire: 3000,
idle: 10000
}
})
После запуска вы должны увидеть в консоли SELECT 1+1 AS result
. Это значит, что подключение прошло успешно:

Методы
У Sequelize есть множество методов, которые позволяют удобно взаимодействовать с базой данных. Но перед тем как начать их рассматривать, нам нужно сделать некоторые подготовительные работы.
Создание таблицы в базе и ORM класса в проекте
Для начала давайте создадим таблицу users
в базе данных, а после ORM класс в Node.js для взаимодействия с ней:

Теперь нам нужно создать нужный класс модели в нашем проекте. Для этого создайте папку models
и добавьте там файл users.js
. Добавьте в файл этот код:
// Db
const { DataTypes } = require('sequelize')
const db = require('../db.js')
const Users = db.define('users',
// Описание таблиц
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
firstname: {
type: DataTypes.STRING,
allowNull: false
},
lastname: {
type: DataTypes.STRING,
allowNull: false
},
comment: {
type: DataTypes.TEXT,
allowNull: true
},
order_by: {
type: DataTypes.INTEGER,
allowNull: false
},
file_id: {
type: DataTypes.INTEGER,
allowNull: true
}
},
// Опции
{
timestamps: false
}
)
module.exports = Users
Теперь импортируйте в нужное место и используйте по назначению.

Создание элемента
const Users = require('./models/users.js')
await Users.create({
firstname: 'Иван',
lastname: 'Иванов',
comment: 'Классный парень',
order_by: 10
})
Если какие-то поля в описании модели имеют allowNull: false
, и вы попытаетесь создать сущность без них, то фреймворк выдаст ошибку.
Обновление элемента
const Users = require('./models/users.js')
await Users.update({
firstname: 'Сергей'
}, {
where: {
user_id: 1
}
})
Удаление элемента
const Users = require('./models/users.js')
await Users.destroy({
where: {
user_id: 1
}
})
Найти один элемент
const Users = require('./models/users.js')
const user = await Users.findOne({
where: {
user_id: 1
}
})
Найти много элементов
const Users = require('./models/users.js')
const user = await Users.findAll({
where: {
order_by: 10
}
})
Если хотите указать лимит, то можно добавить атрибуты offset
и limit
к аргументам объекта:
const Users = require('./models/users.js')
const user = await Users.findAll({
where: {
order_by: 10
},
offset: 0,
limit: 10
})
А если хотите получить какие-то конкретные поля (а не все), то достаточно указать аргумент attributes
и передать туда массив с нужными полями:
const Users = require('./models/users.js')
const user = await Users.findAll({
attributes: ['firstname', 'lastname', 'order_by'],
where: {
order_by: 10
},
offset: 0,
limit: 10
})
Если хотите все отсортировать, достаточно указать атрибут order
и указать, какую сортировку будем делать и по какому полю:
const Users = require('./models/users.js')
const user = await Users.findAll({
attributes: ['firstname', 'lastname', 'order_by'],
where: {
order_by: 10
},
offset: 0,
limit: 10,
order: [
['order_by', 'ASC']
]
})
Кроме ASC
(по возрастанию) можно указать DESC
(по убыванию).
Сложные условия
Для сложных условий существует оператор Op
. Он поддерживает множество конструкций, например: and
, or
, not in
, in
, like
, between
, not between
, регулярные выражения. Давайте продемонстрируем парочку примеров.
Или order_by
равно 10 или user_id
равно 1:
const { Op } = require('sequelize')
const Users = require('./models/users.js')
const user = await Users.findAll({
where: {
[Op.or]: {
order_by: 10,
user_id: 1
}
}
})
Все. Но лишь бы не user_id
под номером 1:
const { Op } = require('sequelize')
const Users = require('./models/users.js')
const user = await Users.findAll({
where: {
user_id: {
[Op.notIn]: [1]
}
}
})
Поиск через iLike
:
const { Op } = require('sequelize')
const Users = require('./models/users.js')
const user = await Users.findAll({
where: {
name: {
[Op.iLike]: `%Иван%`
}
}
})
В MySQL нет оператора iLike
, надо использовать like
. Разница лишь в поиске с учетом регистра и без.
Инкремент и декремент
Прибавить 1 к полю order_by
:
const Users = require('./models/users.js')
await Users.increment('order_by', {
by: 1,
where: {
user_id: 1
}
})
Убавить 1 от поля order_by
:
const Users = require('./models/users.js')
await Users.decrement('order_by', {
by: 1,
where: {
user_id: 1
}
})
Кастомные запросы
const db = require('./db.js')
await db.query('SELECT * FROM users')
Можно связать с моделью, сделав свой собственный метод и вызывать его через model.myMethod()
. Для этого нужно просто добавить метод в модель таким способом:

Связи
Чтобы делать LEFT JOIN
и тянуть данные из связанных таблиц полезно сделать связь. Для этого давайте создадим таблицу files
в базе данных с полями file_id
, path
. И забьем ее данными:

И не забудем добавить file_id
к нужным пользователям в таблице users
:

Теперь надо добавить связь в ORM класс:

Users.hasOne(Files, { foreignKey: 'file_id', sourceKey: 'file_id', as: 'file_info' })
Files.belongsTo(Users, { foreignKey: 'file_id', targetKey: 'file_id', as: 'file_info' })
Главное – выше не забудьте внутрь одной модели импортировать другую модель.
После этого в нужном месте делаете так:
const Users = require('./models/users.js')
const Files = require('./models/files.js')
const result = await Users.findOne({
include: [
{
model: Files,
as: 'file_info'
}
],
where: {
user_id: 1
}
})
Результат вас должен приятно удивить:

Можно делать include
с «обратной» стороны, если вы сделали belongsTo
. Это значит, что можно делать include
не только из основного класса, но и дополнительного (с кем связались через belongsTo
). В нашем случае из класса Files
. Также, кроме hasOne
есть еще hasMany
для «подгрузки» множества элементов.
Отмена транзакции
const Users = require('./models/users.js')
const transaction = await Users.sequelize.transaction()
const result = await Users.create({
firstname: 'Иван',
lastname: 'Иванов',
comment: 'Классный парень',
order_by: 10
}, {
transaction
})
if (result.user_id > 25) {
await transaction.rollback()
} else {
await transaction.commit()
}
Показанным способом вы можете отменять транзакции в базе данных. Главное – не забывайте использовать commit()
для подтверждения транзакции и rollback()
для ее отмены.
В этой статье мы рассмотрели потрясающую ORM для Node.js – Sequelize. Мы научились:
- извлекать данные с различными условиями;
- устанавливать лимиты;
- сортировать результат;
- обновлять и удалять данные;
- писать свои запросы;
- отменять транзакции.
Комментарии