Share This
Связаться со мной
Крути в низ
Categories
//Sequelize, Node.js и PostgreSQL: примеры использования ORM

Sequelize, Node.js и PostgreSQL: примеры использования ORM

sequelize nodejs i postgresql primery ispolzovanija orm 39c1bc3 - Sequelize, Node.js и PostgreSQL: примеры использования ORM

Технический директор компании vverh.digital. JavaScript программист, любитель Kotlin и Swift. Когда начинаешь делать очередной проект, появляется желание упростить себе жизнь и лишний раз не писать SQL-запросы. В таком случае было бы неплохо познакомиться с технологией ORM.

sequelize nodejs i postgresql primery ispolzovanija orm ff3e0e4 - Sequelize, Node.js и PostgreSQL: примеры использования ORM

Что такое 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).

app.js

         const db = require('./db.js') db.authenticate()   .catch(error => console.error(error))     

db.js

         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 nodejs i postgresql primery ispolzovanija orm 1b7fba4 - Sequelize, Node.js и PostgreSQL: примеры использования ORM

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека фронтендера» Интересно, перейти к каналу

Методы

У Sequelize есть множество методов, которые позволяют удобно взаимодействовать с базой данных. Но перед тем как начать их рассматривать, нам нужно сделать некоторые подготовительные работы.

Создание таблицы в базе и ORM класса в проекте

Для начала давайте создадим таблицу users в базе данных, а после ORM класс в Node.js для взаимодействия с ней:

sequelize nodejs i postgresql primery ispolzovanija orm bc737ef - Sequelize, Node.js и PostgreSQL: примеры использования ORM

Теперь нам нужно создать нужный класс модели в нашем проекте. Для этого создайте папку 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     

Теперь импортируйте в нужное место и используйте по назначению.

sequelize nodejs i postgresql primery ispolzovanija orm 9ef91c5 - Sequelize, Node.js и PostgreSQL: примеры использования ORM

Для примера.

Создание элемента

         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(). Для этого нужно просто добавить метод в модель таким способом:

sequelize nodejs i postgresql primery ispolzovanija orm 2238e53 - Sequelize, Node.js и PostgreSQL: примеры использования ORM

Связи

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

sequelize nodejs i postgresql primery ispolzovanija orm e42eb9c - Sequelize, Node.js и PostgreSQL: примеры использования ORM

Таблица files в базе данных.

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

sequelize nodejs i postgresql primery ispolzovanija orm 5d715fa - Sequelize, Node.js и PostgreSQL: примеры использования ORM

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

sequelize nodejs i postgresql primery ispolzovanija orm 0beed30 - Sequelize, Node.js и PostgreSQL: примеры использования 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   } })     

Результат вас должен приятно удивить:

sequelize nodejs i postgresql primery ispolzovanija orm 4b70221 - Sequelize, Node.js и PostgreSQL: примеры использования ORM

У автора стоит плагин для Google Chrome JSON Viewer

Можно делать 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. Мы научились:

  • извлекать данные с различными условиями;
  • устанавливать лимиты;
  • сортировать результат;
  • обновлять и удалять данные;
  • писать свои запросы;
  • отменять транзакции.

Материалы по теме

  • 🐳🐘 Прочный фундамент для API: Docker + Node.js + Nginx + Postgres

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close