Olá! Neste post, falaremos sobre a utilização de bancos de dados MySQL com Node.js! Utilizarei o driver node-mysql2.
Instalação
Para instalá-lo, execute o comando
1 |
npm install mysql2 |
A instalação também pode ser feita adicionando o pacote mysql2
à lista de dependências de seu arquivo package.json
. Para maiores detalhes consulte package.json.
Configuração
Crie o arquivo `config/database.js’ em seu projeto, e adicione as linhas a seguir, fazendo as alterações necessárias nos parâmetros de configuração.
1 2 3 4 5 6 7 8 |
exports.config = { 'default' : { 'host' : 'localhost', 'user' : 'root', 'password' : 'root', 'database' : 'blog' } }; |
Veja a lista completa das possíveis configurações aqui.
Utilização Básica
Para estabelecer uma conexão com o banco de dados, adicione as linhas a seguir.
1 2 3 |
var db_config = require('../config/database.js'), mysql = require('mysql'), db_connection = mysql.createConnection(db_config); |
Para realizar operações de banco de dados, é bastante simples:
1 2 3 4 5 6 7 8 9 |
connection.connect(); connection.query('SELECT 1 + 1 AS solution', function(err, rows, fields) { if (err) throw err; console.log('The solution is: ', rows[0].solution); }); connection.end(); |
O método end()
fecha a conexão com o banco de dados, aguardando que todas as consultas pendentes sejam realizadas antes disso.
Prepared Statements
Para proteger-se contra SQL Injection, recomenda-se a utilização de prepared_statementssempre que uma consulta utilizar dados vindos do usuário. Além disso, quando várias consultas similares forem utilizadas, as consultas são executadas de maneira muito mais eficiente.
1 2 3 4 5 6 7 8 9 10 |
connection.execute('SELECT 1 + ? + ? AS result', [5, 6], function(err, rows) { // rows: [ { result: 12 } ] // internamente 'SELECT 1 + ? + ? AS result' é preparado primeiro. // Nas próximas execuções, o statement em cache é reutilizado, // sem a necessidade de ser preparado novamente. }); // fecha o statement em cache. // Se ele não estiver em cache, nenhuma operação é realizada. connection.unprepare('select 1 + ? + ? as result'); |
Se preferir, você pode preparar o statement manualmente.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
connection.prepare('select ? + ? as tests', function(err, statement) { // statement.parameters - array com as definições das colunas. Possui tamanho igual ao número de parâmetros (no caso, 2) // statement.columns - array com as definições das colunas do statement. // statement.id // statement.query statement.execute([1, 2], function(err, rows, columns) { // -> [ { tests: 3 } ] }); //note que não há callback aqui. O protocolo não envia confirmação sobre essa operação. statement.close(); }); |
Utilizando Pool de Conexões
Você pode, também, utilizar um pool de conexões. Para tanto, adicione ao arquivoconfig/database.js
a seguinte linha:
1 |
'connectionLimit' : 50 |
Esse parâmetro diz o número máximo de conexões que podem ser realizadas em simultâneo com o banco de dados.
A seguir, podemos obter conexões do pool.
1 2 3 4 5 6 7 8 9 10 11 |
var pool = mysql.createPool(db_config.config.default); pool.getConnection(function(err, connection) { // utilize a conexão connection.query( 'SELECT something FROM sometable', function(err, rows) { // devolva-a ao pool connection.release(); // Não utilize mais a conexão, ela foi devolvida ao pool }); }); |
Transações
Utilizar transações é bastante simples.
1 2 3 4 5 6 7 8 9 10 11 12 |
connection.beginTransaction(function(err) { connection.query('INSERT INTO table SET foo=?', 'bar', function(err result){ if (err){ connection.rollback(); } connection.commit(function(err){ if (err){ connection.rollback(); } }); }) }); |
O tratamento de erros foi simplificado por questões de legibilidade.
As funções beginTransaction
, commit
e rollback
são apenas formas simplificadas de se executar os comandos START_TRANSACTION
, COMMIT
e ROLLBACK
no banco de dados. Contudo, alguns comandos podem gerar commits implícitos.
Utilizando Promessas
Infelizmente este pacote não suporta, nativamente, a utilização de promessas. Contudo, você pode utilizar as funções promisify()
e promisifyAll()
do pacote bluebird.