Если объем данных большой, то удобнее воспользоваться базой данных. В качестве примера рассмотрим доступ к базе данных MySQL с помощью пакета mysql2. Установим пакет:
C:\book\e1>npm install mysql2В раздел dependencies будет добавлена следующая строка:
"dependencies": {
"mysql2": "^2.2.5"
}Теперь нам понадобится собственно СУБД MySQL, а также программа для управления базой данных phpMyAdmin. Обе программы входят в состав пакета XAMPP. Именно им мы и воспользуемся.
Программа phpMyAdmin написана на языке PHP, поэтому, если вы хотите администрировать базы данных, вместе с сервером MySQL необходимо запустить и Web-сервер Apache. Для этого открываем XAMPP Control Panel (C:\xampp\xampp-control.exe) и щелкаем на кнопках Start напротив пунктов Apache и MySQL. Далее запускаем Web-браузер и в адресной строке вводим http://localhost/phpmyadmin/. В итоге должна отобразиться стартовая страница программы phpMyAdmin.
Создадим новую базу данных. Для этого слева щелкаем на ссылке Создать БД. Справа в поле Имя базы данных вводим название electron. Из списка Сравнение выбираем пункт utf8_general_ci. Нажимаем кнопку Создать. Новая база данных отобразится в списке слева.
Подключение к базе данных осуществляется с помощью метода createConnection(). Формат метода:
const mysql = require('mysql2/promise');
Promise<Connection> = mysql.createConnection(<Опции>);В качестве параметра указывается объект со следующими основными свойствами:
host — домен, на котором расположен сервер MySQL;user — имя пользователя;password — пароль пользователя;database — название базы данных.В случае успешного подключения метод возвращает объект Promise, содержащий объект соединения Connection. Отключиться от базы данных позволяет метод end():
Promise<void> = conn.end([<Опции>]);При нажатии кнопки подключимся к базе данных:
document.getElementById('btn1').addEventListener('click', async () => {
try {
let conn = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'electron'
});
console.log('Подключено');
await conn.end();
} catch (e) {
console.log(e);
}
});Если все сделано правильно, то в окне консоли получим сообщение Подключено. В противном случае отобразится сообщение об ошибке.
Для создания таблицы можно воспользоваться методом query() объекта Connection. Формат метода:
Promise<results, fields> = conn.query(<SQL-запрос>[, <Данные>]);Давайте добавим в базу данных electron три таблицы (листинг 9.4).
Листинг 9.4. Создание таблицы
async function connect() {
try {
let conn = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'electron'
});
return conn;
} catch (e) {
console.log(e);
return null;
}
}
document.getElementById('btn2').addEventListener('click', async () => {
let conn = await connect();
if (!conn) return;
try {
await conn.query("CREATE TABLE `user` ("
+ "`id_user` mediumint(9) auto_increment, "
+ "`email` char(50), "
+ "`passw` char(32), "
+ "PRIMARY KEY (`id_user`), "
+ "UNIQUE KEY (`email`) "
+ ") ENGINE=MyISAM DEFAULT CHARSET=utf8");
await conn.query("CREATE TABLE `rubr` ("
+ "`id_rubr` mediumint(6) auto_increment, "
+ "`name_rubr` char(150), "
+ "PRIMARY KEY (`id_rubr`) "
+ ") ENGINE=MyISAM DEFAULT CHARSET=utf8");
await conn.query("CREATE TABLE `site` ("
+ "`id_site` mediumint(9) auto_increment, "
+ "`id_user` mediumint(9), "
+ "`id_rubr` mediumint(6), "
+ "`url` char(255), "
+ "`title` char(80), "
+ "`msg` text, "
+ "`iq` tinyint, "
+ "PRIMARY KEY (`id_site`), "
+ "KEY (`id_rubr`) "
+ ") ENGINE=MyISAM DEFAULT CHARSET=utf8");
console.log('Таблицы созданы');
} catch (e) {
console.log(e);
}
finally {
try {
await conn.end();
} catch (e) { }
}
});Добавить записи в таблицу можно несколькими способами. Начнем с уже знакомого нам метода query() объекта Connection. Добавим пользователя в таблицу user:
let [results, fields] = await conn.query(
"INSERT INTO `user` (`email`, `passw`)"
+ " VALUES ('user1@mail.ru', 'password')");Если нам необходимо узнать какой индекс был автоматически сгенерирован при добавлении записи (поле id_user в таблице user обозначено как auto_increment), то обратимся к свойству insertId объекта results:
console.log('Индекс новой записи:', results.insertId);Запрос можно также выполнить с помощью метода execute() объекта Connection. Формат метода:
Promise<results, fields> = conn.execute(<SQL-запрос>[, <Данные>]);Пример добавления нового пользователя:
let [results, fields] = await conn.execute(
"INSERT INTO `user` (`email`, `passw`)"
+ " VALUES ('user2@mail.ru', 'пароль')");
console.log('Индекс новой записи:', results.insertId);В некоторых случаях в SQL-запрос необходимо подставлять данные, полученные от пользователя. Если данные не обработать и подставить в SQL-запрос, то пользователь получает возможность видоизменить запрос и, например, зайти в закрытый раздел без ввода пароля. Чтобы значения были правильно подставлены, необходимо использовать подготовленные запросы. С составе SQL-запроса вместо значений следует указать символ вопроса:
"INSERT INTO `rubr` VALUES (?, ?)"Сами данные следует передать в виде массива во втором параметре. При этом все специальные символы внутри строки будут автоматически экранированы. Давайте добавим несколько рубрик в таблицу rubr:
let arr = ['Программирование', 'Музыка',
'Поисковые \' " порталы', 'Кино'];
for (const value of arr) {
await conn.execute(
'INSERT INTO `rubr` (`name_rubr`) VALUES (?)',
[value]);
}
console.log('Добавлено');Добавим два сайта в таблицу site:
let sql = 'INSERT INTO `site` (`id_user`, `id_rubr`, `url`,'
+ ' `title`, `msg`, `iq`) VALUES (?, ?, ?, ?, ?, ?)';
await conn.execute(sql,
[1, 1, 'http://python.org', 'Python',
'Язык программирования Python', 50]);
await conn.execute(sql,
[1, 3, 'http://google.ru', 'Гугль', 'Поисковый портал', 80]);
console.log('Добавлено');Изменим название рубрики с индексом 3 и удалим рубрику с индексом 4 (листинг 9.5).
let [results] = await conn.execute("UPDATE `rubr` "
+ "SET `name_rubr`='Поисковые порталы' "
+ "WHERE `id_rubr`=3");
console.log('Изменено записей:', results.changedRows);
let [results2] = await conn.execute("DELETE FROM `rubr` "
+ "WHERE `id_rubr`=4");
console.log('Удалено записей:', results2.affectedRows);Получим все записи из таблицы rubr с сортировкой по имени рубрики:
let [results, fields] = await conn.query(
'SELECT * FROM `rubr` ORDER BY `name_rubr`');
let msg = '';
for (let i = 0; i < results.length; i++) {
msg += results[i]['id_rubr'] + ' '
+ results[i]['name_rubr'] + '<br>';
}
let res = document.getElementById('result');
res.innerHTML = msg;Результат доступен через переменную results, а описание полей через переменную fields.
Получим записи сразу из трех таблиц, выполнив всего один запрос:
let [results, fields] = await conn.query(
"SELECT `site`.`url` AS `site_url`, "
+ "`site`.`title` AS `site_title`, "
+ "`rubr`.`name_rubr` AS `rubr_name`, "
+ "`user`.`email` AS `user_email` "
+ "FROM `site`, `rubr`, `user` "
+ "WHERE `site`.`id_rubr`=`rubr`.`id_rubr` "
+ "AND `site`.`id_user`=`user`.`id_user`");
let msg = '';
for (let i = 0; i < results.length; i++) {
msg += results[i]['site_url'] + '<br>';
msg += results[i]['site_title'] + '<br>';
msg += results[i]['rubr_name'] + '<br>';
msg += results[i]['user_email'] + '<br><br>';
}
let res = document.getElementById('result');
res.innerHTML = msg;Результат:
http://python.org
Python
Программирование
user1@mail.ru
http://google.ru
Гугль
Поисковые порталы
user1@mail.ru