SPRINT 11 . Работа с базами данных node.js. Последовательные запросы

Материалы

Текст

В предыдущих юнитах мы научились подключаться к базе данных в Node.js и получать данные из таблиц. Для выборки данных мы использовали пакет mysql и такой синтаксис:


conn.query(query, (err, result, field) =>{
    console.log(err);
    console.log(result);
        // console.log(field);
});

Обратите внимание, что результат мы можем получить только внутри функции, там, где прописан console.log. Таким образом, если нам нужно сделать 2 последовательных запроса - то следующий запрос мы должны делать внутри функции коллбека. Т.е. так:


conn.query(query, (err, result, field) =>{
    console.log(err);
    console.log(result);
        // console.log(field);
        conn.query(query2, (err, result, field) =>{
            console.log(err);
            console.log(result);
                // console.log(field);
        });
});

Как видите, мы наблюдаем callbackhell или ад коллбеков. Даже при двух последовательных запросах - уже вложенность зашкаливает. Увы, очень часто приходится делать последовательные запросы к базе данных, и желательно избегать ада коллбеков.

Итак, наш кейс на сегодня - как сделать последовательные запросы в node.js (синхронные запросы к базе данных в node.js). Самое интересное, что если мы вспомним урок по чтению файлов то для файлов есть как синхронный, так и асинхронный запрос. Увы, с базой данной все сложнее.

Для решения используем пакет mysql2, установим его:

npm i mysql2

Подключим его, однако в отличие от предыдущих пакетов мы подключим его так:

const mysql = require('mysql2/promise');

Да, мы будем использовать Promise. Однако синтаксис promise очень громоздкий. Заменим его оберткой async await.

Создадим подключение к базе ( на примере локальной базы данных).


const config = {
    host: "localhost", //127.0.0.1
    user: "root",
    database: "node_test",
    password: ""
};

Давайте сделаем такую задачу. Пусть у нас в таблице user есть две строки, которые содержат firstname пользователей. Давайте мы вычитаем firstname пользователя с email test@ua и присвоим такое имя пользователю с email iv@ua. Причем сделаем это в виде двух последовательных операций.

Итак, мы будем пользоваться await, а данный синтаксис применим только async функциям. Напишем функцию вида:


    async function main() {
        const conn = await mysql.createConnection(config);
        const [rows, fields] = await conn.execute('SELECT * FROM user where email="test@ua"');
        console.log(rows[0]['firstname']);
        await conn.execute('UPDATE user SET firstname="'+rows[0]['firstname']+'" WHERE email="iv@ua"');
        conn.end();
    }

Как видите мы изменили чуть структуру запроса. Теперь перед операцией conn.execute мы ставим await - тем самым сообщая о синхронном запросе. Результат мы получаем в rows. А во втором запросе мы тоже используем await и делаем его после первого. Если вы написали корректно, то во второй записи сменится имя.

Для того, чтобы функция сработала, мы должны ее вызвать.

main()

В некоторых случаях удобно возвращать результат для последующих операций. Тогда можно применять такой синтаксис.


async function main() {
    const conn = await mysql.createConnection(config);
    const [rows, fields] = await conn.execute('SELECT * FROM user ');
    //console.log(rows);
    conn.end();
    return rows;
}


async function f()  {
    let a = await main();
    console.log(a);
};

f();

Как видите вызывать async функцию тоже нужно через await внутри async функции.

Итак, мы научились делать последовательные запросы с минимальным синтаксисом в node.js.

TASKS

task 1

Для работы с базой данных используется mysql2.Все действия в задачах производим над таблицей user(таблицу создайте на основе файла node_unit_11.sql).Настройки подключения к базе данных должны быть вынесены в отдельный файл config.js и require в данный файл.

Напишите функцию f1(все функции в задании async), которая возвращает age пользователя с email = iv@ua.

task 2

Создайте функцию f2, которая возвращает coin (число) пользователя с возрастом 46.

task 3

Создайте функцию f3, которая возвращает true если у пользователя с lastname Petr монет больше 15 или false если меньше или равно.

task 4
Материалы юнита доступны после покупки курса
task 5
Материалы юнита доступны после покупки курса
task 6
Материалы юнита доступны после покупки курса