Node.js с MySQL

Содержание
  1. node-mysql: модуль node.js, реализующий протокол MySQL Это драйвер node.js для mysql. Написан на JavaScript, не требует компиляции. Он обеспечивает почти все соединения/запросы из MySQL. Node-mysql, вероятно, является одним из лучших модулей, используемых для работы с базой данных MySQL, и этот модуль активно поддерживается. Мы предполагаем, что вы уже установили MySQL и node.js в среде Windows или Linux. Вот пример получения первой строки из таблицы «Сотрудники», принадлежащей базе данных «hr»: var mysql = require (' mysql '); var connection = mysql.createConnection ({хост:' localhost ', пользователь:' root ', пароль:' datasoft123 ', база данных:' hr '}); connection.connect (); connection.query (' SELECT * ОТ служащих, функция (err, rows, fields) {if (err) throw err; console.log (rows [0]);}); connection.end (); Вывод: {EMPLOYEE_ID: 100, FIRST_NAME: 'Steven', LAST_NAME: 'King', EMAIL: '[email protected]', PHONE_NUMBER: '515.123.4567', HIRE_DATE: Среда, 17 июня 1987 г., 00:00:00 GMT + 0530 (индийское стандартное время), JOB_ID: 'AD_PRES', SALARY: 24000, COMMISSION_PCT: 0, MANAGER_ID: 0, DEPARTMENT_ID: 90} От приведенный выше пример y вы можете узнать, как создать новое соединение и закрыть соединение. Содержание: Установить драйвер MySQL node.js Создание и завершение соединений, параметры соединения Обработка ошибок Параметры SSL Объединение соединений, параметров и событий в пул Экранирование значений запросов, идентификаторов Подготовка запросов Хранимые процедуры Соединения Транзакции Таймауты Установите MySQL node.js драйвер $ npm install mysql Вы можете установить последнюю версию с Github, чтобы проверить исправление ошибки. В этом случае используйте следующую команду: $ npm install felixge/node-mysql Create connection Вот код для установления соединения: var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'example. org ', пользователь:' root ', пароль:' datasoft123 '}); connection.connect (function (err) {if (err) {console.error (' error connected: '+ err.stack); return;} console .log ('connected as id' + connection.threadId);}); Вот еще один способ установить соединение с помощью запроса: var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'localhost', user: 'root', password: 'datasoft123'}); connection.query ( 'SELECT 1', function (err, rows) {if (err) {console.error ('error connected:' + err.stack); return;} console. log ('connected!');}); Вариант подключения Имя Описание host Имя хоста базы данных. По умолчанию — localhost. port Номер порта для подключения. По умолчанию — 3306. localAddress Исходный IP-адрес, используемый для TCP-соединения. (Необязательно) socketPath Путь к сокету домена unix для подключения. При использовании хост и порт игнорируются. user Пользователь MySQL для аутентификации как. пароль Пароль этого пользователя MySQL. база данных Имя базы данных, которая будет использоваться для этого соединения (необязательно). charset Кодировка для связь. На уровне SQL MySQL это называется «сопоставлением» (например, utf8_general_ci). Если указана кодировка уровня SQL (например, utf8mb4), то используется сопоставление по умолчанию для этой кодировки. (По умолчанию: ‘UTF8_GENERAL_CI’) часовой пояс Часовой пояс, используемый для хранения местных дат. По умолчанию: ‘local’. connectTimeout Миллисекунды до истечения времени ожидания во время первоначального подключения к серверу MySQL. (По умолчанию: 10 секунд) stringifyObjects Строковые объекты вместо преобразования в значения. См. Выпуск №501. (По умолчанию: ‘false’) insecureAuth Разрешить подключение к экземплярам MySQL, которые запрашивают старый (небезопасный) метод аутентификации . (По умолчанию: false) typeCast Определяет, следует ли преобразовывать значения столбцов в собственные типы JavaScript. (По умолчанию: true) queryFormat Функция настраиваемого формата запроса. См. Пользовательский формат. supportBigNumbers При работе с большими числами (столбцы BIGINT и DECIMAL) в базе данных следует включить эта опция (по умолчанию: false). bigNumberStrings Включение поддержкиBigNumbers и bigNumberStrings приводит к большим числам (столбцы BIGINT и DECIMAL) всегда возвращаться как объекты String JavaScript (по умолчанию: false). Включение supportBigNumbers, но отключение bigNumberStrings вернет большие числа в виде объектов String только в том случае, если они не могут быть точно представлены с помощью объектов JavaScript Number (что происходит, когда они превышают [-2 ^ 53, + 2 ^ 53] диапазон), в противном случае они будут возвращены как числовые объекты. Этот параметр игнорируется, если supportBigNumbers отключен. dateStrings Принудительно возвращать типы даты (TIMESTAMP, DATETIME, DATE) в виде строк, а не в виде объектов JavaScript Date. (По умолчанию: false) debug Печатает детали протокола в стандартный вывод. (По умолчанию: false) trace Создает трассировку стека при ошибке, чтобы включить место вызова входа в библиотеку («длинные трассировки стека «). Незначительное снижение производительности для большинства вызовов. По умолчанию установлено значение true. multipleStatements Разрешить несколько операторов mysql на запрос. Будьте осторожны, это подвергнет вас атакам с использованием SQL-инъекций. (По умолчанию: false) flags Список флагов подключения для использования, кроме флагов по умолчанию. Также возможно занести в черный список те, которые используются по умолчанию. Для получения дополнительной информации проверьте флаги подключения. ssl объект с параметрами ssl или строку, содержащую имя профиля ssl. См. Параметры SSL. Примечание. Сначала выполняется попытка анализа значений запроса как JSON, и если это не удается, предполагается, что это строки с открытым текстом. Завершение соединения Есть два способа завершить соединение: метод end () метод destroy () Вы можете завершить соединение, вызвав метод end (): connection .end (function (err) {//Соединение сейчас разорвано}); Это обеспечит выполнение всех ранее поставленных в очередь запросов перед отправкой пакета COM_QUIT на сервер MySQL . Если фатальная ошибка возникает до того, как пакет COM_QUIT может быть отправлен, обратному вызову будет предоставлен аргумент err, но соединение будет разорвано независимо от этого. метод destroy (): Этот метод немедленно завершает соединение. Кроме того, destroy () гарантирует, что для соединения больше не будут запускаться события или обратные вызовы. connection.destroy (); В отличие от end (), метод destroy () не принимает аргумент обратного вызова. Переключение пользователей/изменение состояния соединения: MySQL предлагает команду changeUser, которая позволяет вам изменять текущего пользователя и другие аспекты соединения без выключения базового сокета: connection.changeUser ({user: 'user2 '}, function (err) {if (err) throw err;}); Доступные параметры: Имя Описание user Имя нового пользователя (по умолчанию — предыдущий). password Пароль нового пользователя (по умолчанию предыдущая). charset Новая кодировка (по умолчанию предыдущая). база данных Новая база данных ase (по умолчанию используется предыдущий). Иногда полезным побочным эффектом этой функции является то, что эта функция также сбрасывает любое состояние соединения (переменные, транзакции и т. д.). Ошибки, обнаруженные во время этой операции, обрабатываются этим модулем как фатальные ошибки подключения. Обработка ошибок Есть несколько вариантов обработки ошибок в этом модуле: Все ошибки, создаваемые этим модулем, являются экземплярами Объект ошибки JavaScript. Кроме того, они имеют два свойства: код ошибки: Ошибка сервера MySQL (например, ‘ER_ACCESS_DENIED_ERROR’) Ошибка node.js (например, ‘ECONNREFUSED’) Внутренняя ошибка (например, ‘PROTOCOL_CONNECTION_LOST’) err.fatal: Boolean, указывающий, является ли эта ошибка конечной для объекта подключения. Неустранимые ошибки распространяются (чтобы вызвать умножение любым процессом) на все ожидающие обратные вызовы. В приведенном ниже примере фатальная ошибка возникает при попытке ввести недопустимое имя пользователя. Поэтому в следующем примере объект ошибки распространяется на оба ожидающих обратного вызова: var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'localhost ', пользователь:' roott ', пароль:' datasoft123 ',}); connection.connect (function (err) {console.log (err.code); console.log (err.fatal);}); connection.query ('SELECT 1', function (err) {console.log (err.code); console.log (err.fatal);}); Вывод: ER_ACCESS_DENIED_ERRORtrueER_ACCESS_DENIED_ERRORtrue В этом примере фатальная ошибка вызвана недопустимым пользователем. var mysql = require (' mysql '); var connection = mysql.createConnection ({host:' localhost ', пользователь:' roott ', пароль:' datasoft123 '}); connection.query (' SELECT 1 ', function (err) {if (err) {console.log (err.code); console.log (err.fatal);}}); connection.end (); Вывод: E: nodejs> node test.js ER_ACCESS_DENIED_ERROR true Делегируются нормальные ошибки только к обратному вызову, которому они принадлежат. В следующем примере только первый обратный вызов получает ошибку (неправильное имя базы данных), второй запрос работает должным образом: var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'localhost', user: 'root', password: 'datasoft123',});//Неверное имя базы данныхconnection.query ('USE kkk', function (err, rows) {console. log (err.code);//'ER_BAD_DB_ERROR'}); connection.query ('SELECT 1', function (err, rows) {//null console.log (err);//длина строки 1 console. log (rows.length);}); Сервер отключается: Вы можете потерять соединение с сервером MySQL из-за сетевых проблем, время ожидания сервера, перезапуск сервера или сбой. Все эти события считаются фатальными ошибками и имеют код ошибки = ‘PROTOCOL_CONNECTION_LOST’. Дополнительные сведения см. В разделе «Обработка ошибок». Повторное подключение выполняется путем установления нового подключения. После завершения существующий объект подключения не может быть повторно подключен по дизайну.. При использовании Pool отключенные соединения будут удалены из пула, освобождая место для создания нового соединения при следующем вызове getConnection. Параметры SSL Параметр ssl в параметрах подключения принимает строку или объект. При задании строки он использует один из включенных предопределенных профилей SSL. Включены следующие профили: «Amazon RDS»: этот профиль предназначен для подключения к серверу Amazon RDS и содержит CA с https://rds.amazonaws.com/ doc/rds-ssl-ca-cert.pem При подключении к другим серверам вам нужно будет предоставить объект параметров в том же формате, что и crypto.createCredentials. Обратите внимание, что аргументы ожидают строку сертификата, а не имя файла сертификата. Вот простой пример: var connection = mysql.createConnection ({host: 'localhost', ssl: {ca: fs.readFileSync (__ dirname + '/mysql-ca .crt ')}}); Вы также можете подключиться к серверу MySQL без надлежащего предоставления соответствующего ЦС, которому можно доверять. Вы не должны этого делать. var connection = mysql.createConnection ({host: 'localhost', ssl: {//НЕ ДЕЛАЙТЕ ЭТОГО//правильно настройте ваш CA чтобы доверять соединению rejectUnauthorized: false}}); var connection = mysql.createConnection ({host: 'localhost', ssl: {//НЕ СДЕЛАЙТЕ ЭТО//правильно настройте центр управления, чтобы доверять соединению rejectUnauthorized: false}}); Объединение соединений Пул соединений — это кеш соединений с базой данных, поддерживаемых, чтобы эти соединения можно было повторно использовать, когда потребуются будущие запросы к базе данных. Пулы соединений используются для повышения производительности выполнения команд в базе данных. Использовать пул напрямую. var mysql = require ('mysql'); var pool = mysql.createPool ({connectionLimit: 10, host: 'localhost', user: 'root', password: 'datasoft123'}); pool.query ('SELECT 1 + 1 решение AS ', function (err, rows, fields) {if (err) throw err; console.log (' Решение: ', rows [0] .solution);}); Когда вы закончите соединение, просто вызовите connection.release (), и соединение вернется в пул, готовое к повторному использованию кем-то другим. var mysql = require ('mysql'); var pool = mysql.createPool ({connectionLimit: 10, host: 'localhost', user: 'root', password: 'datasoft123', database: 'hr'} ); pool.getConnection (function (err, connection) {//Используем соединение connection.query ('SELECT * from employee', function (err, rows) {//И готово с соединением. console.log (rows [ 0]); connection.release () ; //Не используйте здесь соединение, оно было возвращено в пул. });}); Если вы хотите закрыть соединение и удалить его из пула, используйте вместо этого connection.destroy (). Пул создаст новое соединение, когда оно понадобится в следующий раз. Закрытие всех соединений в пуле Когда вы выполняются с использованием пула, вам необходимо завершить все соединения, иначе цикл событий Node.js останется активным, пока соединения не будут закрыты сервером MySQL. Метод end принимает необязательный обратный вызов, который вы можете использовать, чтобы узнать, когда все соединения будут завершены. Соединения завершаются корректно, поэтому все ожидающие запросы будут по-прежнему завершены, а время завершения пула будет отличаться. После вызова pool.end () pool.getConnection и другие операции больше не могут выполняться Параметры пула Пул поддерживает все варианты обычного подключения. Кроме того, вот несколько дополнительных параметров: Имя Описание resumeTimeout Время в миллисекундах до истечения тайм-аута во время получения соединения. Это немного отличается от connectTimeout, потому что получение соединения пула не всегда включает в себя установление соединения. (По умолчанию: 10 секунд) waitForConnections Определяет действие пула, когда нет доступных подключений и достигнут предел. Если true, пул поставит запрос на соединение в очередь и вызовет его, когда он станет доступным. Если false, пул немедленно перезвонит с ошибкой. (По умолчанию: true) connectionLimit Максимальное количество одновременных соединений. (По умолчанию: 10) queueLimit Максимальное количество запросов на соединение, которые пул будет помещать в очередь перед возвратом ошибки из getConnection. Если установлено значение 0, нет ограничений на количество запросов на подключение в очереди. (По умолчанию: 0) События пула соединение: Пул будет генерировать событие соединения, когда новое соединение будет установлено внутри пула. Если вам нужно установить переменные сеанса в соединении до того, как оно будет использовано, вы можете прослушать событие соединения. pool.on ('connection', function (connection) { connection.query ('SET SESSION auto_increment_increment = 1')}); поставить в очередь: Пул генерирует событие постановки в очередь, когда обратный вызов был поставлен в очередь для ожидания доступного соединения. pool.on ('enqueue', function () {console.log ('Waiting для доступного слота подключения ');}); Экранирование значений запроса SQL-инъекция — это метод (как и другие механизмы веб-атак) для атаки на данные управляемые приложения. Эта атака может обойти брандмауэр и затронуть полностью исправленную систему. Злоумышленник использует плохо отфильтрованные или неправильно экранированные символы, встроенные в операторы SQL, для анализа данных переменных из пользовательского ввода.. Злоумышленник вводит произвольные данные, чаще всего запрос к базе данных, в строку, которая в конечном итоге выполняется базой данных через веб-приложение (например, форму входа в систему). Чтобы избежать атак с использованием SQL-инъекций, вы всегда должны избегать любых данных, предоставленных пользователем, прежде чем использовать их в SQL-запросе. Вы можете сделать это с помощью методов connection.escape () или pool.escape (): var userId = 'some user provided value'; var sql = 'SELECT * FROM users WHERE id =' + connection.escape (userId); connection.query (sql, function (err, results) {//...}); В качестве альтернативы вы можете использовать? символы в качестве заполнителей для значений, которые вы хотели бы экранировать следующим образом: connection.query ('SELECT * FROM users WHERE id =?', [userId], function (err, results) {//...}); Различные типы значений экранируются по-разному, вот как: Числа остаются нетронутыми Логические значения преобразуются в строки true/false Объекты Date преобразуются в строки ‘YYYY-mm-dd HH: ii: ss’ Буферы преобразованы в шестнадцатеричные строки, например X’0fa5 ‘ Строки безопасно экранируются Массивы превращаются в список, например [‘a’, ‘b’] превращается в ‘a’, ‘b’ Вложенные массивы превращаются в сгруппированные списки (для массовых вставок), например [[‘a’, ‘b’], [‘c’, ‘d’]] превращается в (‘a’, ‘b’), (‘c’, ‘d’) Объекты превращаются в пары key = ‘val’. Вложенные объекты преобразуются в строки. undefined/null преобразуются в NULL NaN/Infinity остаются как есть. MySQL не поддерживает их, и попытка вставить их в качестве значений вызовет ошибки MySQL, пока они не будут реализованы. Вот пример оператора INSERT INTO: var post = {id: 1, title: 'Hello MySQL'}; var query = connection.query ('INSERT INTO posts SET?', post, function (err, result) {//Аккуратно!}); console.log (query.sql); //ВСТАВИТЬ В сообщения SET `id` = 1,` title` = 'Hello MySQL' Вы также можете напрямую использовать функцию экранирования, см. Следующий пример: var query = "ВЫБРАТЬ * ИЗ сообщений WHERE title =" + mysql.escape ("Hello MySQL"); console.log (query); //ВЫБРАТЬ * ИЗ сообщений WHERE title = 'Hello MySQL' Escaping query identifiers Поскольку идентификатор SQL (имя базы данных/таблицы/столбца) предоставляется пользователем , вы должны экранировать его с помощью mysql.escapeId (идентификатор), connection.escapeId (идентификатор) или pool.escapeId (идентификатор) следующим образом: var sorter = 'date'; var sql = 'SELECT * FROM posts ORDER BY '+ connection.escapeId (sorter); connection.query (sql, function (err, results) {//...}); Он также поддерживает добавление квалифицированных идентификаторов . Он будет экранировать обе части. var sorter = 'date'; var sql = 'SELECT * FROM posts ORDER BY' + connection.escapeId ('posts. '+ sorter); connection.query (sql, function (err, results) {//...}); В качестве альтернативы вы можете использовать ?? символы в качестве заполнителей для идентификаторов, которые вы хотели бы экранировать следующим образом: var userId = 1; var columns = ['username', 'email']; var query = connection.query ('SELECT ?? ОТ ?? ГДЕ id =? ', [Столбцы,' пользователи ', userId], функция (ошибка, результаты) {//...}); console.log (query.sql); //ВЫБЕРИТЕ `username`,` email` FROM `users` WHERE id = 1 Примечание: последняя последовательность символов является экспериментальной, и синтаксис может измениться. Когда вы передаете объект в .escape () или .query (), .escapeId () используется, чтобы избежать внедрения SQL в ключи объекта. Подготовка запросов MySQL 5.6 обеспечивает поддержку подготовленных операторов на стороне сервера. Эта поддержка использует преимущества эффективного бинарного протокола клиент/сервер, доступного начиная с MySQL 4.1. Вы можете использовать mysql.format для подготовки запроса с несколькими точками вставки, используя правильное экранирование для идентификаторов и значений. Вот простой пример: var sql = "SELECT * FROM ?? WHERE ?? =?"; Var insertts = ['users', 'id', userId]; sql = mysql .format (sql, insert); После этого у вас будет действительный экранированный запрос, который затем можно безопасно отправить в базу данных. Это полезно, если вы хотите подготовить запрос перед его отправкой в ​​базу данных. Поскольку mysql.format предоставляется из SqlString.format, у вас также есть возможность (но не обязательно) передавать stringifyObject и часовой пояс, что позволяет вам предоставлять настраиваемые средства преобразования объектов в строки, а также для конкретного местоположения/часового пояса- осведомленная дата. Пользовательский формат: Если вы предпочитаете использовать другой тип escape-формата запроса, есть параметр конфигурации подключения, который вы можете использовать для определения функции пользовательского формата . Вы можете получить доступ к объекту подключения, если хотите использовать встроенную функцию .escape () или любую другую функцию подключения. Вот пример того, как реализовать другой формат: connection.config.queryFormat = function (query, values) {if (! values) вернуть запрос; return query.replace (/: ( w +)/g, function (txt, key) {if (values.hasOwnProperty (key)) {return this.escape (values ​​[key]);} return txt;} .bind (this));}; connection.query ("UPDATE posts SET title =: title", {title: "Hello MySQL"}); Получение идентификатора вставленной строки: Если вы вставляете строку в таблицу с автоинкрементным первичным ключом, вы можете получить идентификатор вставки следующим образом: connection.query ('INSERT INTO posts SET ? ', {title:' test '}, function (err, result) {if (err) throw err; console.log (result.insertId);}); При работе с большими числа (выше предела точности числа JavaScript), вам следует рассмотреть возможность включения опции поддержки BigNumbers, чтобы иметь возможность читать идентификатор вставки в виде строки, иначе он выдаст. Этот параметр также необходим при извлечении больших чисел из базы данных, иначе вы получите значения, округленные до сотен или тысяч из-за ограничения точности. Получение числа затронутых строк. Вы можете получить количество затронутых строк с помощью оператора вставки, обновления или удаления. «changedRows» отличается от «loadedRows» тем, что он не считает обновленные строки, значения которых не были изменены. connection.query ('УДАЛИТЬ ИЗ сообщений WHERE title = "неправильно"', function (err, result) {if (err) throw err; console.log ('deleted' + result.affectedRows + 'rows');}) Получение идентификатора соединения Вы можете получить идентификатор подключения MySQL (» идентификатор потока «) данного соединения с использованием свойства threadId. connection.connect (function (err) {if (err) throw err; console.log ('connected as id' + connection. threadId);}); Параллельное выполнение запросов: Протокол MySQL является последовательным, это означает что вам нужно несколько подключений для параллельного выполнения запросов. Вы можете использовать пул для управления соединениями, один простой подход — создать одно соединение для каждого входящего HTTP-запроса. Строки запроса потоковой передачи Иногда вам может потребоваться выбрать большое количество строк и обработать каждую из них как они получены. Это можно сделать так: var query = connection.query ('SELECT * FROM posts'); query .on ('error', function (err) {//Обработка ошибки, an После этого также будет сгенерировано событие 'end'}) .on ('fields', function (fields) {//пакеты полей для следующих строк}) .on ('result', function (row) {//Приостановка соединения полезна, если ваша обработка включает соединение ввода-вывода. Pause (); processRow (row, function () {connection.resume ();});}) .on ('end', function () {//все строки были получены}); Обратите внимание на несколько моментов в приведенном выше примере: Обычно вы хотите получить определенный количество строк перед началом дросселирования соединения с помощью pause (). Это число будет зависеть от количества и размера ваших строк. pause ()/resume () работают с базовым сокетом и анализатором. Вам гарантируется, что после вызова pause () больше не будет запускаться никаких событий result. Вы НЕ ДОЛЖНЫ предоставлять обратный вызов методу query () при потоковой передаче строк. Событие ‘result’ будет срабатывать для обеих строк, а также для пакетов OK, подтверждающих успех запроса INSERT/UPDATE. Кроме того, вам может быть интересно узнать, что это в настоящее время невозможно передавать отдельные столбцы строк, они всегда будут буферизироваться полностью. Если у вас есть хороший вариант использования потоковой передачи больших полей в MySQL и из MySQL, я хотел бы узнать ваши мысли и предложения по этому поводу.. Запросы с несколькими операторами: Поддержка нескольких операторов отключена по соображениям безопасности (это позволяет использовать SQL-инъекции, если значения не экранированы должным образом). Чтобы использовать эту функцию, вы должны включить ее для вашего соединения: var connection = mysql.createConnection ({multipleStatements: true}); После включения вы можете выполнить несколько запросов операторов, как и любой другой запрос: connection.query ('SELECT 1; SELECT 2', function (err, results) {if (err) throw err;//`results` is массив с одним элементом для каждого оператора в запросе: console.log (results [0]);//[{1: 1}] console.log (results [1]);//[{2: 2}] }); Кроме того, вы также можете передавать результаты нескольких запросов операторов: var query = connection.query ('SELECT 1; SELECT 2'); query .on ('fields', function (fields, index) {//поля для следующих строк результатов}) .on ('result', function (row, index) {//index ссылается на оператор, которому принадлежит этот результат to (начинается с 0)}); Если один из операторов в вашем запросе вызывает ошибку, результирующий объект Error содержит свойство err.index, которое сообщает вам, какой оператор вызвал Это. MySQL также прекратит выполнение любых оставшихся операторов при возникновении ошибки. Обратите внимание, что интерфейс для потоковой передачи нескольких запросов операторов является экспериментальным, и я с нетерпением жду отзывов по нему. Хранимые процедуры Вы можете вызывать хранимые процедуры из ваших запросов, как и с любым другим драйвером mysql. Вот исходный код процедуры: DELIMITER $$ CREATE PROCEDURE my_procedure_User_Variables () BEGIN SET @x = 15; УСТАНОВИТЬ @y = 10; ВЫБРАТЬ @x, @y, @ [электронная почта защищена]; END $$ Вывод, когда он был выполнен в MySQL: mysql> CALL my_procedure_User_Variables (); + ------ + ------ + ------- + | @x | @y | @ [адрес электронной почты защищен] | + ------ + ------ + ------- + | 15 | 10 | 5 | + ------ + ------ + ------- + 1 строка в наборе (0,04 сек) Запрос ОК, затронуты 0 строк (0,05 сек) Теперь вызовите хранимую процедуру из node.js: var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'localhost', user: 'root', password : 'datasoft123', база данных: 'hr'}); connection.connect (); connection.query ("ВЫЗОВ my_procedure_User_Variables ();", функция (err, rows) {if (err) throw err; console.log (rows );}); connection.end (); Вывод: [[{'@x': 15, '@y': 10, '@ [email protected] ': 5}], {fieldCount: 0, enabledRows: 0, insertId: 0, serverStatus: 2, warningCount: 0, message:' ', protocol41: true, changedRows: 0}] Объединения Вы можете вызывать JOINS из ваших запросов, как и с любым другим драйвером mysql. Вот пример: Напишите запрос для отображения идентификатора отдела, названия отдела и имени менеджера. См. Базу данных ‘hr’. var mysql = require ('mysql'); var connection = mysql.createConnection ({хост: 'localhost', пользователь: 'root', пароль: 'datasoft123', база данных: 'hr' }); connection.connect (); connection.query ("ВЫБЕРИТЕ d.department_id, d.department_name, e.manager_id, e.first_name ИЗ отделов d INNER JOIN сотрудников e ON (d.manager_id = e.employee_id);", function (err, rows) {if (err) throw err; console.log (rows);}); connection.end (); Вывод: [{Department_id: 10, имя_отдела: 'Администрация', manager_id: 101, first_name: 'Jennifer'}, {Department_id: 20, имя_отдела: 'Маркетинг', manager_id: 100, first_name: 'Michael'}, {Department_id: 30, имя_отдела: 'Закупки', идентификатор_управления: 100, имя_первого_имя: 'День'}, {идентификатор_отдела: 40, имя_отдела: 'Отдел кадров', идентификатор_управления: 101, имя_имя: 'Сьюзен'}, ---------- -------------------------- ------------------------ ------------ Транзакции MySQL (здесь мы поддерживаем версию 5.6) поддерживает локальный t транзакции (в рамках данного клиентского сеанса) с помощью таких операторов, как SET autocommit, START TRANSACTION, COMMIT и ROLLBACK. Вот синтаксис START TRANSACTION, COMMIT и ROLLBACK: START TRANSACTION transaction_characteristic [, transaction_characteristic] ...] transaction_characteristic: WITH CONSISTENT SNAPSHOT | ЧИТАТЬ НАПИСАТЬ | ТОЛЬКО ДЛЯ ЧТЕНИЯ НАЧАТЬ [РАБОТА] ЗАВЕРШИТЬ [РАБОТА] [И [НЕТ] ЦЕПЬ] [[НЕТ] РЕЛИЗ] ОТКАТ [РАБОТА] [И [НЕТ] ЦЕПЬ] [[НЕТ] ВЫПУСК] УСТАНОВИТЬ autocommit = {0 | 1} В node.js поддержка простых транзакций доступна на уровне подключения: connection.beginTransaction (function (err) {if ( err) {throw err;} connection.query ('ВСТАВИТЬ В сообщения SET title =?', title, function (err, result) {if (err) {connection.rollback (function () {throw err;});} var log = 'Post' + result.insertId + 'added'; connection.query ('INSERT INTO log SET data =?', log, function (err, result) {if (err) {connection.rollback (function () {throw err;});} connection.commit (function (err) {if (err) {connection.rollback (function () {throw err;});} console.log ('успех!');}); });});}); Обратите внимание, что beginTransaction (), commit () и rollback () — это просто вспомогательные функции, которые выполняют START TRANSACTION, COMMIT и ROLLBACK команды соответственно. Важно понимать, что многие команды в MySQL могут вызывать неявную фиксацию, как описано в документации MySQL Timeouts Каждая операция требует необязательной опции тайм-аута бездействия. Это позволяет указать соответствующие тайм-ауты для операций. Важно отметить, что эти тайм-ауты не являются частью протокола MySQL, а скорее являются операциями тайм-аута через клиента.. Это означает, что когда истечет время ожидания, соединение, на котором оно возникло, будет разрушено, и дальнейшие операции не могут быть выполнены. //Завершить запрос после 60sconnection.query ({sql : 'SELECT COUNT (*) AS count FROM big_table', timeout: 60000}, function (err, rows) {if (err && err.code === 'PROTOCOL_SEQUENCE_TIMEOUT') {throw new Error ('too long to count table rows! ');} if (err) {throw err;} console.log (rows [0] .count +' rows ');}); Структура базы данных ‘hr’: Новый контент, опубликованный на w3resource: Упражнения по программированию на Scala, практика, решение Python Упражнения Itertools упражнения Python Numpy упражнения пакета Python GeoPy упражнения Python Pandas Python nltk упражнения упражнения Python BeautifulSoup Шаблон формы Composer — менеджер пакетов PHP i> PHPUnit — тестирование PHP Laravel — PHP Framework Angular — JavaScript Framework React — Библиотека JavaScript Vue — JavaScript Framework Jest — JavaScript Testing Framework
  2. Установите MySQL node.js драйвер
  3. Create connection
  4. Обработка ошибок
  5. Параметры SSL
  6. Объединение соединений
  7. Экранирование значений запроса
  8. Escaping query identifiers
  9. Подготовка запросов
  10. Хранимые процедуры
  11. Объединения
  12. Транзакции
  13. Timeouts

node-mysql: модуль node.js, реализующий протокол MySQL

Это драйвер node.js для mysql. Написан на JavaScript, не требует компиляции. Он обеспечивает почти все соединения/запросы из MySQL. Node-mysql, вероятно, является одним из лучших модулей, используемых для работы с базой данных MySQL, и этот модуль активно поддерживается.

Мы предполагаем, что вы уже установили MySQL и node.js в среде Windows или Linux.

Вот пример получения первой строки из таблицы «Сотрудники», принадлежащей базе данных «hr»:

  var mysql = require ('  mysql '); var connection = mysql.createConnection ({хост:' localhost ', пользователь:' root ', пароль:' datasoft123 ', база данных:' hr '}); connection.connect (); connection.query (' SELECT  * ОТ служащих, функция (err, rows, fields) {if (err) throw err; console.log (rows [0]);}); connection.end ();  

Вывод:

 {EMPLOYEE_ID: 100, FIRST_NAME: 'Steven', LAST_NAME: 'King', EMAIL: '[email protected]', PHONE_NUMBER: '515.123.4567', HIRE_DATE:  Среда, 17 июня 1987 г., 00:00:00 GMT + 0530 (индийское стандартное время), JOB_ID: 'AD_PRES', SALARY: 24000, COMMISSION_PCT: 0, MANAGER_ID: 0, DEPARTMENT_ID: 90} 

От приведенный выше пример y вы можете узнать, как создать новое соединение и закрыть соединение.

Содержание:

  • Установить драйвер MySQL node.js
  • Создание и завершение соединений, параметры соединения
  • Обработка ошибок
  • Параметры SSL
  • Объединение соединений, параметров и событий в пул
  • Экранирование значений запросов, идентификаторов
  • Подготовка запросов
  • Хранимые процедуры
  • Соединения
  • Транзакции
  • Таймауты

Установите MySQL node.js драйвер

  $ npm install mysql  

Вы можете установить последнюю версию с Github, чтобы проверить исправление ошибки. В этом случае используйте следующую команду:

  $ npm install felixge/node-mysql  

Create connection

Вот код для установления соединения:

  var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'example.  org ', пользователь:' root ', пароль:' datasoft123 '}); connection.connect (function (err) {if (err) {console.error (' error connected: '+ err.stack); return;} console  .log ('connected as id' + connection.threadId);});  

Вот еще один способ установить соединение с помощью запроса:

  var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'localhost', user: 'root', password: 'datasoft123'}); connection.query (  'SELECT 1', function (err, rows) {if (err) {console.error ('error connected:' + err.stack); return;} console. log ('connected!');});  

Вариант подключения

Имя Описание
host Имя хоста базы данных. По умолчанию — localhost.
port Номер порта для подключения. По умолчанию — 3306.
localAddress Исходный IP-адрес, используемый для TCP-соединения. (Необязательно)
socketPath Путь к сокету домена unix для подключения. При использовании хост и порт игнорируются.
user Пользователь MySQL для аутентификации как.
пароль Пароль этого пользователя MySQL.
база данных Имя базы данных, которая будет использоваться для этого соединения (необязательно).
charset Кодировка для связь. На уровне SQL MySQL это называется «сопоставлением» (например, utf8_general_ci). Если указана кодировка уровня SQL (например, utf8mb4), то используется сопоставление по умолчанию для этой кодировки. (По умолчанию: ‘UTF8_GENERAL_CI’)
часовой пояс Часовой пояс, используемый для хранения местных дат. По умолчанию: ‘local’.
connectTimeout Миллисекунды до истечения времени ожидания во время первоначального подключения к серверу MySQL. (По умолчанию: 10 секунд)
stringifyObjects Строковые объекты вместо преобразования в значения. См. Выпуск №501. (По умолчанию: ‘false’)
insecureAuth Разрешить подключение к экземплярам MySQL, которые запрашивают старый (небезопасный) метод аутентификации . (По умолчанию: false)
typeCast Определяет, следует ли преобразовывать значения столбцов в собственные типы JavaScript. (По умолчанию: true)
queryFormat Функция настраиваемого формата запроса. См. Пользовательский формат.
supportBigNumbers При работе с большими числами (столбцы BIGINT и DECIMAL) в базе данных следует включить эта опция (по умолчанию: false).
bigNumberStrings Включение поддержкиBigNumbers и bigNumberStrings приводит к большим числам (столбцы BIGINT и DECIMAL) всегда возвращаться как объекты String JavaScript (по умолчанию: false).
Включение supportBigNumbers, но отключение bigNumberStrings вернет большие числа в виде объектов String только в том случае, если они не могут быть точно представлены с помощью объектов JavaScript Number (что происходит, когда они превышают [-2 ^ 53, + 2 ^ 53] диапазон), в противном случае они будут возвращены как числовые объекты. Этот параметр игнорируется, если supportBigNumbers отключен.
dateStrings Принудительно возвращать типы даты (TIMESTAMP, DATETIME, DATE) в виде строк, а не в виде объектов JavaScript Date. (По умолчанию: false)
debug Печатает детали протокола в стандартный вывод. (По умолчанию: false)
trace Создает трассировку стека при ошибке, чтобы включить место вызова входа в библиотеку («длинные трассировки стека «). Незначительное снижение производительности для большинства вызовов. По умолчанию установлено значение true.
multipleStatements Разрешить несколько операторов mysql на запрос. Будьте осторожны, это подвергнет вас атакам с использованием SQL-инъекций. (По умолчанию: false)
flags Список флагов подключения для использования, кроме флагов по умолчанию. Также возможно занести в черный список те, которые используются по умолчанию. Для получения дополнительной информации проверьте флаги подключения.
ssl объект с параметрами ssl или строку, содержащую имя профиля ssl. См. Параметры SSL.

Примечание. Сначала выполняется попытка анализа значений запроса как JSON, и если это не удается, предполагается, что это строки с открытым текстом.

Завершение соединения

Есть два способа завершить соединение:

  • метод end ()
  • метод destroy ()

Вы можете завершить соединение, вызвав метод end ():

  connection  .end (function (err) {//Соединение сейчас разорвано});  

Это обеспечит выполнение всех ранее поставленных в очередь запросов перед отправкой пакета COM_QUIT на сервер MySQL . Если фатальная ошибка возникает до того, как пакет COM_QUIT может быть отправлен, обратному вызову будет предоставлен аргумент err, но соединение будет разорвано независимо от этого.

метод destroy ():

Этот метод немедленно завершает соединение. Кроме того, destroy () гарантирует, что для соединения больше не будут запускаться события или обратные вызовы.

  connection.destroy ();  

В отличие от end (), метод destroy () не принимает аргумент обратного вызова.

Переключение пользователей/изменение состояния соединения:

MySQL предлагает команду changeUser, которая позволяет вам изменять текущего пользователя и другие аспекты соединения без выключения базового сокета:

  connection.changeUser ({user: 'user2  '}, function (err) {if (err) throw err;});  

Доступные параметры:

Имя Описание
user Имя нового пользователя (по умолчанию — предыдущий).
password Пароль нового пользователя (по умолчанию предыдущая).
charset Новая кодировка (по умолчанию предыдущая).
база данных Новая база данных ase (по умолчанию используется предыдущий).

Иногда полезным побочным эффектом этой функции является то, что эта функция также сбрасывает любое состояние соединения (переменные, транзакции и т. д.).

Ошибки, обнаруженные во время этой операции, обрабатываются этим модулем как фатальные ошибки подключения.

Обработка ошибок

Есть несколько вариантов обработки ошибок в этом модуле:

Все ошибки, создаваемые этим модулем, являются экземплярами Объект ошибки JavaScript. Кроме того, они имеют два свойства:

  • код ошибки:
    • Ошибка сервера MySQL (например, ‘ER_ACCESS_DENIED_ERROR’)
    • Ошибка node.js (например, ‘ECONNREFUSED’)
    • Внутренняя ошибка (например, ‘PROTOCOL_CONNECTION_LOST’)
  • err.fatal: Boolean, указывающий, является ли эта ошибка конечной для объекта подключения.

Неустранимые ошибки распространяются (чтобы вызвать умножение любым процессом) на все ожидающие обратные вызовы. В приведенном ниже примере фатальная ошибка возникает при попытке ввести недопустимое имя пользователя. Поэтому в следующем примере объект ошибки распространяется на оба ожидающих обратного вызова:

  var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'localhost  ', пользователь:' roott ', пароль:' datasoft123 ',}); connection.connect (function (err) {console.log (err.code); console.log (err.fatal);}); connection.query  ('SELECT 1', function (err) {console.log (err.code); console.log (err.fatal);});  

Вывод:

 ER_ACCESS_DENIED_ERRORtrueER_ACCESS_DENIED_ERRORtrue 

В этом примере фатальная ошибка вызвана недопустимым пользователем.

  var mysql = require ('  mysql '); var connection = mysql.createConnection ({host:' localhost ', пользователь:' roott ', пароль:' datasoft123 '}); connection.query (' SELECT 1 ', function (err) {if (err)  {console.log (err.code); console.log (err.fatal);}}); connection.end ();  

Вывод:

 E:  nodejs> node test.js 
ER_ACCESS_DENIED_ERROR
true

Делегируются нормальные ошибки только к обратному вызову, которому они принадлежат. В следующем примере только первый обратный вызов получает ошибку (неправильное имя базы данных), второй запрос работает должным образом:

  var mysql = require ('mysql'); var  connection = mysql.createConnection ({host: 'localhost', user: 'root', password: 'datasoft123',});//Неверное имя базы данныхconnection.query ('USE kkk', function (err, rows) {console.  log (err.code);//'ER_BAD_DB_ERROR'}); connection.query ('SELECT 1', function (err, rows) {//null console.log (err);//длина строки 1 console.  log (rows.length);});  

Сервер отключается:

Вы можете потерять соединение с сервером MySQL из-за сетевых проблем, время ожидания сервера, перезапуск сервера или сбой. Все эти события считаются фатальными ошибками и имеют код ошибки = ‘PROTOCOL_CONNECTION_LOST’. Дополнительные сведения см. В разделе «Обработка ошибок».

Повторное подключение выполняется путем установления нового подключения. После завершения существующий объект подключения не может быть повторно подключен по дизайну..

При использовании Pool отключенные соединения будут удалены из пула, освобождая место для создания нового соединения при следующем вызове getConnection.

Параметры SSL

Параметр ssl в параметрах подключения принимает строку или объект. При задании строки он использует один из включенных предопределенных профилей SSL. Включены следующие профили:

  • «Amazon RDS»: этот профиль предназначен для подключения к серверу Amazon RDS и содержит CA с https://rds.amazonaws.com/ doc/rds-ssl-ca-cert.pem

При подключении к другим серверам вам нужно будет предоставить объект параметров в том же формате, что и crypto.createCredentials. Обратите внимание, что аргументы ожидают строку сертификата, а не имя файла сертификата. Вот простой пример:

  var connection = mysql.createConnection ({host: 'localhost', ssl: {ca: fs.readFileSync (__ dirname + '/mysql-ca  .crt ')}});  

Вы также можете подключиться к серверу MySQL без надлежащего предоставления соответствующего ЦС, которому можно доверять. Вы не должны этого делать.

  var connection = mysql.createConnection ({host: 'localhost', ssl: {//НЕ ДЕЛАЙТЕ ЭТОГО//правильно настройте ваш CA  чтобы доверять соединению rejectUnauthorized: false}});  
  var connection = mysql.createConnection ({host: 'localhost', ssl: {//НЕ  СДЕЛАЙТЕ ЭТО//правильно настройте центр управления, чтобы доверять соединению rejectUnauthorized: false}});  

Объединение соединений

Пул соединений — это кеш соединений с базой данных, поддерживаемых, чтобы эти соединения можно было повторно использовать, когда потребуются будущие запросы к базе данных. Пулы соединений используются для повышения производительности выполнения команд в базе данных.

Использовать пул напрямую.

  var mysql = require ('mysql'); var pool = mysql.createPool ({connectionLimit: 10, host: 'localhost', user: 'root', password: 'datasoft123'}); pool.query ('SELECT 1  + 1 решение AS ', function (err, rows, fields) {if (err) throw err; console.log (' Решение: ', rows [0] .solution);});  

Когда вы закончите соединение, просто вызовите connection.release (), и соединение вернется в пул, готовое к повторному использованию кем-то другим.

  var mysql = require ('mysql'); var pool = mysql.createPool ({connectionLimit: 10, host: 'localhost', user: 'root', password: 'datasoft123', database: 'hr'}  ); pool.getConnection (function (err, connection) {//Используем соединение connection.query ('SELECT * from employee', function (err, rows) {//И готово с соединением. console.log (rows [  0]); connection.release ()  ; //Не используйте здесь соединение, оно было возвращено в пул.  });});  

Если вы хотите закрыть соединение и удалить его из пула, используйте вместо этого connection.destroy (). Пул создаст новое соединение, когда оно понадобится в следующий раз.

Закрытие всех соединений в пуле

Когда вы выполняются с использованием пула, вам необходимо завершить все соединения, иначе цикл событий Node.js останется активным, пока соединения не будут закрыты сервером MySQL. Метод end принимает необязательный обратный вызов, который вы можете использовать, чтобы узнать, когда все соединения будут завершены. Соединения завершаются корректно, поэтому все ожидающие запросы будут по-прежнему завершены, а время завершения пула будет отличаться. После вызова pool.end () pool.getConnection и другие операции больше не могут выполняться

Параметры пула

Пул поддерживает все варианты обычного подключения. Кроме того, вот несколько дополнительных параметров:

Имя Описание
resumeTimeout Время в миллисекундах до истечения тайм-аута во время получения соединения. Это немного отличается от connectTimeout, потому что получение соединения пула не всегда включает в себя установление соединения. (По умолчанию: 10 секунд)
waitForConnections Определяет действие пула, когда нет доступных подключений и достигнут предел. Если true, пул поставит запрос на соединение в очередь и вызовет его, когда он станет доступным. Если false, пул немедленно перезвонит с ошибкой. (По умолчанию: true)
connectionLimit Максимальное количество одновременных соединений. (По умолчанию: 10)
queueLimit Максимальное количество запросов на соединение, которые пул будет помещать в очередь перед возвратом ошибки из getConnection. Если установлено значение 0, нет ограничений на количество запросов на подключение в очереди. (По умолчанию: 0)

События пула

соединение :

Пул будет генерировать событие соединения, когда новое соединение будет установлено внутри пула. Если вам нужно установить переменные сеанса в соединении до того, как оно будет использовано, вы можете прослушать событие соединения.

  pool.on ('connection', function (connection) {  connection.query ('SET SESSION auto_increment_increment = 1')});  

поставить в очередь :

Пул генерирует событие постановки в очередь, когда обратный вызов был поставлен в очередь для ожидания доступного соединения.

  pool.on ('enqueue', function () {console.log ('Waiting  для доступного слота подключения ');});  

Экранирование значений запроса

SQL-инъекция — это метод (как и другие механизмы веб-атак) для атаки на данные управляемые приложения. Эта атака может обойти брандмауэр и затронуть полностью исправленную систему. Злоумышленник использует плохо отфильтрованные или неправильно экранированные символы, встроенные в операторы SQL, для анализа данных переменных из пользовательского ввода.. Злоумышленник вводит произвольные данные, чаще всего запрос к базе данных, в строку, которая в конечном итоге выполняется базой данных через веб-приложение (например, форму входа в систему).

Чтобы избежать атак с использованием SQL-инъекций, вы всегда должны избегать любых данных, предоставленных пользователем, прежде чем использовать их в SQL-запросе. Вы можете сделать это с помощью методов connection.escape () или pool.escape ():

 var userId = 'some user provided value'; var sql = 'SELECT * FROM users WHERE id ='  + connection.escape (userId); connection.query (sql, function (err, results) {//...}); 

В качестве альтернативы вы можете использовать? символы в качестве заполнителей для значений, которые вы хотели бы экранировать следующим образом:

 connection.query ('SELECT * FROM users WHERE id =?', [userId], function (err, results) {//...}); 

Различные типы значений экранируются по-разному, вот как:

  • Числа остаются нетронутыми
  • Логические значения преобразуются в строки true/false
  • Объекты Date преобразуются в строки ‘YYYY-mm-dd HH: ii: ss’
  • Буферы преобразованы в шестнадцатеричные строки, например X’0fa5 ‘
  • Строки безопасно экранируются
  • Массивы превращаются в список, например [‘a’, ‘b’] превращается в ‘a’, ‘b’
  • Вложенные массивы превращаются в сгруппированные списки (для массовых вставок), например [[‘a’, ‘b’], [‘c’, ‘d’]] превращается в (‘a’, ‘b’), (‘c’, ‘d’)
  • Объекты превращаются в пары key = ‘val’. Вложенные объекты преобразуются в строки.
  • undefined/null преобразуются в NULL
  • NaN/Infinity остаются как есть. MySQL не поддерживает их, и попытка вставить их в качестве значений вызовет ошибки MySQL, пока они не будут реализованы.

Вот пример оператора INSERT INTO:

 var post = {id: 1, title: 'Hello MySQL'}; var query = connection.query ('INSERT INTO posts SET?', post, function (err, result) {//Аккуратно!});  console.log (query.sql); //ВСТАВИТЬ В сообщения SET `id` = 1,` title` = 'Hello MySQL' 

Вы также можете напрямую использовать функцию экранирования, см. Следующий пример:

 var query = "ВЫБРАТЬ * ИЗ сообщений WHERE title =" + mysql.escape ("Hello MySQL"); console.log (query); //ВЫБРАТЬ * ИЗ сообщений WHERE title = 'Hello MySQL' 

Escaping query identifiers

Поскольку идентификатор SQL (имя базы данных/таблицы/столбца) предоставляется пользователем , вы должны экранировать его с помощью mysql.escapeId (идентификатор), connection.escapeId (идентификатор) или pool.escapeId (идентификатор) следующим образом:

 var sorter = 'date'; var sql = 'SELECT  * FROM posts ORDER BY '+ connection.escapeId (sorter); connection.query (sql, function (err, results) {//...}); 

Он также поддерживает добавление квалифицированных идентификаторов . Он будет экранировать обе части.

 var sorter = 'date'; var sql = 'SELECT * FROM posts ORDER BY' + connection.escapeId ('posts. '+ sorter); connection.query (sql, function (err, results) {//...}); 

В качестве альтернативы вы можете использовать ?? символы в качестве заполнителей для идентификаторов, которые вы хотели бы экранировать следующим образом:

 var userId = 1; var columns = ['username', 'email']; var query = connection.query ('SELECT  ?? ОТ ?? ГДЕ id =? ', [Столбцы,' пользователи ', userId], функция (ошибка, результаты) {//...}); console.log (query.sql); //ВЫБЕРИТЕ `username`,` email` FROM `users` WHERE id = 1 

Примечание: последняя последовательность символов является экспериментальной, и синтаксис может измениться.

Когда вы передаете объект в .escape () или .query (), .escapeId () используется, чтобы избежать внедрения SQL в ключи объекта.

Подготовка запросов

MySQL 5.6 обеспечивает поддержку подготовленных операторов на стороне сервера. Эта поддержка использует преимущества эффективного бинарного протокола клиент/сервер, доступного начиная с MySQL 4.1. Вы можете использовать mysql.format для подготовки запроса с несколькими точками вставки, используя правильное экранирование для идентификаторов и значений. Вот простой пример:

 var sql = "SELECT * FROM ?? WHERE ?? =?"; Var insertts = ['users', 'id', userId]; sql = mysql  .format (sql, insert); 

После этого у вас будет действительный экранированный запрос, который затем можно безопасно отправить в базу данных. Это полезно, если вы хотите подготовить запрос перед его отправкой в ​​базу данных. Поскольку mysql.format предоставляется из SqlString.format, у вас также есть возможность (но не обязательно) передавать stringifyObject и часовой пояс, что позволяет вам предоставлять настраиваемые средства преобразования объектов в строки, а также для конкретного местоположения/часового пояса- осведомленная дата.

Пользовательский формат:

Если вы предпочитаете использовать другой тип escape-формата запроса, есть параметр конфигурации подключения, который вы можете использовать для определения функции пользовательского формата . Вы можете получить доступ к объекту подключения, если хотите использовать встроенную функцию .escape () или любую другую функцию подключения.

Вот пример того, как реализовать другой формат:

 connection.config.queryFormat = function (query, values) {if (! values) вернуть запрос;  return query.replace (/: ( w +)/g, function (txt, key) {if (values.hasOwnProperty (key)) {return this.escape (values ​​[key]);} return txt;} .bind  (this));}; connection.query ("UPDATE posts SET title =: title", {title: "Hello MySQL"}); 

Получение идентификатора вставленной строки:

Если вы вставляете строку в таблицу с автоинкрементным первичным ключом, вы можете получить идентификатор вставки следующим образом:

 connection.query ('INSERT INTO posts SET  ? ', {title:' test '}, function (err, result) {if (err) throw err; console.log (result.insertId);}); 

При работе с большими числа (выше предела точности числа JavaScript), вам следует рассмотреть возможность включения опции поддержки BigNumbers, чтобы иметь возможность читать идентификатор вставки в виде строки, иначе он выдаст.

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

Получение числа затронутых строк.

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

«changedRows» отличается от «loadedRows» тем, что он не считает обновленные строки, значения которых не были изменены.

 connection.query ('УДАЛИТЬ ИЗ сообщений WHERE title = "неправильно"', function (err, result) {if (err) throw err;  console.log ('deleted' + result.affectedRows + 'rows');}) 

Получение идентификатора соединения

Вы можете получить идентификатор подключения MySQL (» идентификатор потока «) данного соединения с использованием свойства threadId.

 connection.connect (function (err) {if (err) throw err; console.log ('connected as id' + connection.  threadId);}); 

Параллельное выполнение запросов:

Протокол MySQL является последовательным, это означает что вам нужно несколько подключений для параллельного выполнения запросов. Вы можете использовать пул для управления соединениями, один простой подход — создать одно соединение для каждого входящего HTTP-запроса.

Строки запроса потоковой передачи

Иногда вам может потребоваться выбрать большое количество строк и обработать каждую из них как они получены. Это можно сделать так:

 var query = connection.query ('SELECT * FROM posts'); query .on ('error', function (err) {//Обработка ошибки, an  После этого также будет сгенерировано событие 'end'}) .on ('fields', function (fields) {//пакеты полей для следующих строк}) .on ('result', function (row) {//Приостановка соединения полезна, если ваша обработка включает соединение ввода-вывода. Pause (); processRow (row, function () {connection.resume ();});}) .on ('end', function () {//все строки были получены}); 

Обратите внимание на несколько моментов в приведенном выше примере:

  • Обычно вы хотите получить определенный количество строк перед началом дросселирования соединения с помощью pause (). Это число будет зависеть от количества и размера ваших строк.
  • pause ()/resume () работают с базовым сокетом и анализатором. Вам гарантируется, что после вызова pause () больше не будет запускаться никаких событий result.
  • Вы НЕ ДОЛЖНЫ предоставлять обратный вызов методу query () при потоковой передаче строк.
  • Событие ‘result’ будет срабатывать для обеих строк, а также для пакетов OK, подтверждающих успех запроса INSERT/UPDATE.

Кроме того, вам может быть интересно узнать, что это в настоящее время невозможно передавать отдельные столбцы строк, они всегда будут буферизироваться полностью. Если у вас есть хороший вариант использования потоковой передачи больших полей в MySQL и из MySQL, я хотел бы узнать ваши мысли и предложения по этому поводу..

Запросы с несколькими операторами:

Поддержка нескольких операторов отключена по соображениям безопасности (это позволяет использовать SQL-инъекции, если значения не экранированы должным образом). Чтобы использовать эту функцию, вы должны включить ее для вашего соединения:

 var connection = mysql.createConnection ({multipleStatements: true}); 

После включения вы можете выполнить несколько запросов операторов, как и любой другой запрос:

 connection.query ('SELECT 1; SELECT 2', function (err, results) {if (err) throw err;//`results` is  массив с одним элементом для каждого оператора в запросе: console.log (results [0]);//[{1: 1}] console.log (results [1]);//[{2: 2}]  }); 

Кроме того, вы также можете передавать результаты нескольких запросов операторов:

 var query = connection.query ('SELECT 1; SELECT 2'); query  .on ('fields', function (fields, index) {//поля для следующих строк результатов}) .on ('result', function (row, index) {//index ссылается на оператор, которому принадлежит этот результат  to (начинается с 0)}); 

Если один из операторов в вашем запросе вызывает ошибку, результирующий объект Error содержит свойство err.index, которое сообщает вам, какой оператор вызвал Это. MySQL также прекратит выполнение любых оставшихся операторов при возникновении ошибки.

Обратите внимание, что интерфейс для потоковой передачи нескольких запросов операторов является экспериментальным, и я с нетерпением жду отзывов по нему.

Хранимые процедуры

Вы можете вызывать хранимые процедуры из ваших запросов, как и с любым другим драйвером mysql. Вот исходный код процедуры:

 DELIMITER $$ CREATE PROCEDURE my_procedure_User_Variables () BEGIN SET @x = 15;  УСТАНОВИТЬ @y = 10;  ВЫБРАТЬ @x, @y, @ [электронная почта защищена];  END $$ 

Вывод, когда он был выполнен в MySQL:

 mysql> CALL my_procedure_User_Variables ();  + ------ + ------ + ------- + |  @x |  @y |  @ [адрес электронной почты защищен] |  + ------ + ------ + ------- + |  15 |  10 |  5 |  + ------ + ------ + ------- + 1 строка в наборе (0,04 сек) Запрос ОК, затронуты 0 строк (0,05 сек) 

Теперь вызовите хранимую процедуру из node.js:

 var mysql = require ('mysql'); var connection = mysql.createConnection ({host: 'localhost', user: 'root', password  : 'datasoft123', база данных: 'hr'}); connection.connect (); connection.query ("ВЫЗОВ my_procedure_User_Variables ();", функция (err, rows) {if (err) throw err; console.log (rows  );}); connection.end (); 

Вывод:

 [[{'@x': 15, '@y': 10, '@  [email protected] ': 5}], {fieldCount: 0, enabledRows: 0, insertId: 0, serverStatus: 2, warningCount: 0, message:' ', protocol41: true, changedRows: 0}] 

Объединения

Вы можете вызывать JOINS из ваших запросов, как и с любым другим драйвером mysql. Вот пример:

Напишите запрос для отображения идентификатора отдела, названия отдела и имени менеджера. См. Базу данных ‘hr’.

 var mysql = require ('mysql'); var connection = mysql.createConnection ({хост: 'localhost', пользователь: 'root', пароль: 'datasoft123', база данных: 'hr'  }); connection.connect (); connection.query ("ВЫБЕРИТЕ d.department_id, d.department_name, e.manager_id, e.first_name ИЗ отделов d INNER JOIN сотрудников e ON (d.manager_id = e.employee_id);",  function (err, rows) {if (err) throw err; console.log (rows);}); connection.end (); 

Вывод:

  [{Department_id: 10, имя_отдела: 'Администрация', manager_id: 101, first_name: 'Jennifer'}, {Department_id: 20, имя_отдела: 'Маркетинг', manager_id: 100, first_name: 'Michael'}, {Department_id: 30,  имя_отдела: 'Закупки', идентификатор_управления: 100, имя_первого_имя: 'День'}, {идентификатор_отдела: 40, имя_отдела: 'Отдел кадров', идентификатор_управления: 101, имя_имя: 'Сьюзен'}, ----------  -------------------------- ------------------------  ------------ 

Транзакции

MySQL (здесь мы поддерживаем версию 5.6) поддерживает локальный t транзакции (в рамках данного клиентского сеанса) с помощью таких операторов, как SET autocommit, START TRANSACTION, COMMIT и ROLLBACK. Вот синтаксис START TRANSACTION, COMMIT и ROLLBACK:

 START TRANSACTION transaction_characteristic [, transaction_characteristic] ...] transaction_characteristic: WITH CONSISTENT SNAPSHOT |  ЧИТАТЬ НАПИСАТЬ |  ТОЛЬКО ДЛЯ ЧТЕНИЯ НАЧАТЬ [РАБОТА] ЗАВЕРШИТЬ [РАБОТА] [И [НЕТ] ЦЕПЬ] [[НЕТ] РЕЛИЗ] ОТКАТ [РАБОТА] [И [НЕТ] ЦЕПЬ] [[НЕТ] ВЫПУСК] УСТАНОВИТЬ autocommit = {0 |  1} 

В node.js поддержка простых транзакций доступна на уровне подключения:

  connection.beginTransaction (function (err) {if (  err) {throw err;} connection.query ('ВСТАВИТЬ В сообщения SET title =?', title, function (err, result) {if (err) {connection.rollback (function () {throw err;});}  var log = 'Post' + result.insertId + 'added'; connection.query ('INSERT INTO log SET data =?', log, function (err, result) {if (err) {connection.rollback (function ()  {throw err;});} connection.commit (function (err) {if (err) {connection.rollback (function () {throw err;});} console.log ('успех!');});  });});});  

Обратите внимание, что beginTransaction (), commit () и rollback () — это просто вспомогательные функции, которые выполняют START TRANSACTION, COMMIT и ROLLBACK команды соответственно. Важно понимать, что многие команды в MySQL могут вызывать неявную фиксацию, как описано в документации MySQL

Timeouts

Каждая операция требует необязательной опции тайм-аута бездействия. Это позволяет указать соответствующие тайм-ауты для операций. Важно отметить, что эти тайм-ауты не являются частью протокола MySQL, а скорее являются операциями тайм-аута через клиента.. Это означает, что когда истечет время ожидания, соединение, на котором оно возникло, будет разрушено, и дальнейшие операции не могут быть выполнены.

 //Завершить запрос после 60sconnection.query ({sql  : 'SELECT COUNT (*) AS count FROM big_table', timeout: 60000}, function (err, rows) {if (err && err.code === 'PROTOCOL_SEQUENCE_TIMEOUT') {throw new Error ('too long to count table  rows! ');} if (err) {throw err;} console.log (rows [0] .count +' rows ');});  

Структура базы данных ‘hr’:


  • Новый контент, опубликованный на w3resource:
  • Упражнения по программированию на Scala, практика, решение
  • Python Упражнения Itertools
  • упражнения Python Numpy
  • упражнения пакета Python GeoPy
  • упражнения Python Pandas
  • Python nltk упражнения
  • упражнения Python BeautifulSoup
  • Шаблон формы
  • Composer — менеджер пакетов PHP i>
  • PHPUnit — тестирование PHP
  • Laravel — PHP Framework
  • Angular — JavaScript Framework
  • React — Библиотека JavaScript
  • Vue — JavaScript Framework
  • Jest — JavaScript Testing Framework



Оцените статью
nanomode.ru
Добавить комментарий