Usando MySQL com NodeJS
Você sabe o que vem a ser um banco de dados? Não? Então vem comigo que eu te explico 🙂
No mundo da tecnologia, um banco de dados é uma forma com que temos para armazenar os dados que são gerados pela nossa aplicação (ou quem chegam por meio dos nossos usuários).
Ou seja, tanto dados internos, gerados pelo próprio sistema, quanto dados externos, advindos dos nossos usuários.
Pensa em um banco de dados como um grande armário, que foi feito para armazenar as suas roupas (e entre outras coisas a mais).
Dependendo da manufatura do seu armário, ele pode estar dividido em diversas partes, com: prateleiras, gavetas, seções e por aí vai....
Se você for um tipo de pessoa organizada, você vai separar cada peça de roupa dentro do seu armário de forma estruturarada, ou seja, sapatos ficam na primeira gaveta, blusas em outra, roupas íntimas em outra e por aí vai....
Voltando no mundo da tecnologia, um banco de dados é uma forma com que temos para armazenar informações relevantes (de maneira organizada) da nossa aplicação, para que possamos usá-las futuramente.
Por exemplo: O Portal da Micilini possui um banco de dados, e o artigo (roupa) que você está lendo neste exato momento, está armazenado em uma de nossas tabelas (gavetas) do nosso banco de dados (armário).
O que é um banco de dados?
Agora que você já tem mais ou menos uma ideia do que seja um banco de dados, vamos fazer o uso de palavras um pouco mais rebuscadas para definí-lo 😉
Um banco de dados é um conjunto organizado de informações ou dados estruturados, armazenados de forma que possam ser facilmente acessados, gerenciados e atualizados.
É por meio de um banco de dados que iremos armazenar os dados do sistema, e também dos nossos usuários, de forma rápida e eficiente.
A grande maioria dos projetos que nós vemos por aí na internet, fazem o uso de banco de dados para armazenar dados e informações.
Um banco de dados, possui alguns conceitos básicos, como:
Tabelas: um banco de dados geralmente é composto de tabelas que contêm linhas e colunas. Cada linha representa um registro, e cada coluna representa um campo ou atributo dos dados.
Colunas: é o local onde categorizamos os dados que estamos inserindo.
Dados: é o valor em si que é inserido dentro das colunas. Eles podem ser inseridos, modificados, atualizados e removidos de uma tabela.
SQL: muitas vezes, os bancos de dados utilizam uma linguagem de consulta estruturada (SQL - Structured Query Language) para acessar e manipular os dados.
Relacionamentos: são ligações que acontecem entre tabelas. Aqui é o lugar onde usamos os comandos JOIN
do SQL
.
CRUD: é um acrônimo que representa as quatro operações básicas que podem ser realizadas em um banco de dados, como Create
, Read
, Update
e Delete
.
Além disso, existem diferentes tipos de bancos de dados, como os banco de dados relacionais (ex: MySQL, PostgreSQL), banco de dados não relacionais, que é o caso do NoSQL (ex: MongoDB), e em nuvem (como é o caso do Firebase da Google).
A ideia desta lição não é te dar um entendimento profundo sobre banco de dados, mas sim, como usar o MySQL em conjunto com a sua aplicação feita com NodeJS.
E falando em MySQL, vamos dar uma breve introdução nele 😉
O que é o MySQL?
MySQL é um sistema de gerenciamento de banco de dados relacional (RDBMS) de código aberto.
Ele utiliza a linguagem SQL
(Structured Query Language) para manipular, armazenar e recuperar dados em um banco de dados.
Sendo amplamente utilizado em aplicações da web, ele é capaz de servir nossos sistemas de forma eficiente e com uma facilidade de uso enorme.
É importante que você saiba, que o MySQL é um sistema de gerenciamento, ou seja, ele não é apenas uma biblioteca que será instalada na pasta do seu projeto, fazendo com que você só precise disso para armazenar os seus dados.
Não, o MySQL é um aplicativo que instalamos na nossa máquina local (ou servidor online), e que funciona como uma "espécie de API", que sempre será chamada quando a nossa aplicação necessitar 😎
Ou seja, o MySQL é uma aplicação que vai ficar rodando por de baixo dos panos dentro da nossa máquina, sempre pronto para fornecer informações relevantes quando necessário.
E sim, o MySQL possui uma lógica de funcionamento por trás, onde roda uma sintaxe chamada de SQL
😉
Instalando o MySQL + MySQL WorkBench (Windows)
Caso você estiver utilizando o Windows, preparamos um passo a passo exclusivo para você instalar o MySQL e o MySQL WorkBench na sua máquina local (caso ainda não tenha).
Para seguir com o processo de instalação, basta seguir os links abaixo:
Ambas as ferramentas são indispensáveis para você seguir a diante com essa lição, portanto, não se esqueça de instalá-las e configurá-las, ok?
Criando uma tabela de testes
Com o MySQL já instalado na sua máquina local, que tal criarmos uma tabela de testes no nosso banco de dados, e que servirá de exemplo a ser usada dentro da nossa aplicação em NodeJS? 🤓
Com o terminal (Prompt de Comando) aberto em qualquer pasta do seu computador, vamos acessar o nosso banco de dados com o seguinte comando:
mysql -u root -p
E não se esqueça de informar a senha que você configurou na hora em que instalou o MySQL.
Com o terminal do próprio MySQL aberto, digite o comando abaixo para criar um novo banco de dados chamado de nodejs
:
CREATE DATABASE nodejs;
Para usar este banco de dados, usamos o comando use
+ nome do banco de dados:
USE nodejs;
A partir de agora estaremos dentro do banco de dados que acabamos de criar, chamado de nodejs
🙃
Vamos criar a nossa primeira tabela?
Para isso, pegue o comando abaixo e insira dentro do terminal do mysql
e pressione [ENTER].
CREATE TABLE usuarios (
id INT AUTO_INCREMENT PRIMARY KEY,
nome VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
senha VARCHAR(255) NOT NULL,
data_criacao datetime NOT NULL
);
É por meio do comando CREATE TABLE
que dizemos ao MySQL para criar uma tabela cujo nome será usuarios
, e que conterá as seguintes colunas:
id
(inteiro, chave primária, auto-incremento)
nome
(VARCHAR para nome do usuário)
email
(VARCHAR para e-mail do usuário, único)
senha
(VARCHAR para a senha)
data_criacao
(TIMESTAMP para data de criação, valor padrão CURRENT_TIMESTAMP)
Feito isso, já estamos prontos para brincar com o MySQL junto com o NodeJS 😉
Criando nosso projeto de testes
Antes de colocarmos a mão na massa, é deveras importante que você configure o seu projeto inicial.
Para isso, eu criei uma pasta chamada de MySQL-NodeJS dentro da minha área de trabalho (desktop):
Com o seu terminal (Prompt de Comando) aberto na pasta raiz que acabamos de criar, precisamos inicializar o nosso projeto por meio do NPM
, sendo assim, execute o seguinte comando abaixo:
npm init -y
A flag -y
, como você já deve saber, cria um novo projeto de forma enxuta, respondendo SIM para tudo 😅
Feito isso, partiu instalar a biblioteca do MySQL no nosso projeto!
Instalando a biblioteca do MySQL
No NodeJS, nós podemos usar uma biblioteca chamada de mysql2
, e que pode ser instalada no nosso projeto de forma gratuita.
Mas antes, gostaria que você entendesse o seguinte: no caso da biblioteca mysql, nós desenvolvedores costumamos chamá-la de driver em vez de biblioteca, uma vez que qualquer tipo de pacote/biblioteca que é usado para se conectar com um banco de dados, como convenção, chamamos ele de driver em vez de pacote/biblioteca, ok?
Sendo assim, partiu instalar o nosso driver no nosso projeto 😄
Com o seu terminal (Prompt de Comando) aberto na pasta raiz do seu projeto, execute o seguinte comando abaixo:
npm install mysql2
Após a instalação, não se esqueça de criar o arquivo index.js
na pasta raiz do projeto 😋
Configurações inciais do driver mysql
Com o index.js
aberto no seu editor de códigos favorito, a primeira coisa que você precisa fazer é importar a biblioteca do mysql2
no projeto. E isso pode ser feito da seguinte forma:
const mysql = require('mysql2');
Agora, precisamos configurar uma conexão com o banco de dados, e para isso, você pode usar a seguinte estrutura abaixo:
//Cria a conexão com o banco de dados
const conn = mysql.createConnection({
host: 'localhost', //ou 127.0.0.1
user: 'root', //ou qualquer outro usuário que você tenha criado
password: '', //a senha relacionada ao usuário
database: 'nodejs', //o banco de dados que você criou
});
//Realiza a conexão com o banco de dados
conn.connect(function(error){
//Veririca se houve algum tipo de erro durante a conexão com o banco
if(error){
console.log('Houve um erro ao conectar com o banco', error);
}
//Se estiver tudo OK, ele gera uma mensagem no console.
console.log('Conectado com o MySQL com sucesso!');
});
No código acima, nós criamos uma variável chamada de conn
, que executa o método createConnection
do driver importado (mysql2
).
Esse método precisa ser configurado com as credênciais de acesso do banco de dados, tais como:
host
: é o host do seu banco, que pode ser localhost
, 127.0.0.1
, ou qualquer outro IP externo.
user
: é o usuário do seu banco de dados.
password
: é a senha relacionado com o usuário do seu banco de dados.
database
: é o banco de dados que a nossa aplicação terá acesso. (No caso desta lição, iremos usar o banco que criamos anteriormente, que é o nodejs)
Veja como ficou o index.js
:
const mysql = require('mysql2');
//Cria a conexão com o banco de dados
const conn = mysql.createConnection({
host: 'localhost', //ou 127.0.0.1
user: 'root', //ou qualquer outro usuário que você tenha criado
password: '', //a senha relacionada ao usuário
database: 'nodejs', //o banco de dados que você criou
});
//Realiza a conexão com o banco de dados
conn.connect(function(error){
//Veririca se houve algum tipo de erro durante a conexão com o banco
if(error){
console.log('Houve um erro ao conectar com o banco', error);
}
//Se estiver tudo OK, ele gera uma mensagem no console.
console.log('Conectado com o MySQL com sucesso!');
});
Se tudo estiver OK, após a execução da sua aplicação, você receberá a seguinte mensagem no console:
Indicando que a comunicação com o MySQL foi estabelecida com sucesso! 🥳
Inserindo dados no banco de dados (inseguro)
Com a sua tabela usuarios
já criada, e o seu projeto configurado, vamos ver aprender a como inserir alguns dados dentro da nossa tabela 😉
Para inserir os dados, você precisa criar e executar uma query SQL
(representada por uma string) diretamentamente no seu código.
Se você já tem experiência com banco de dados, sabe que um INSERT
pode ser executado da seguinte forma na tabela de usuarios
, a fim de inserir novos dados:
INSERT INTO `usuarios` (`id`, `nome`, `email`, `senha`, `data_criacao`) VALUES (NULL, 'Micilini Roll', 'hey@micilini.com', 'MICILINI_É_DEZ', CURRENT_TIMESTAMP);
No caso do NodeJS em conjunto com o mysql2
, precisamos fazer o uso do método query
da seguinte forma:
//Realiza a inserão de dados no banco de dados:
const dados = {
nome: 'Micilini Roll',
email: 'hey@micilini.com',
senha: 'MICILINI_É_DEZ',
data: new Date() // Data e hora atuais
};
// Função para formatar a data em 'YYYY-MM-DD HH:MM:SS'
function formatDateToMySQL(date) {
const pad = (n) => n < 10 ? '0' + n : n;
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
const sql = `INSERT INTO usuarios (nome, email, senha, data_criacao) VALUES ('${dados.nome}', '${dados.email}', '${dados.senha}', '${formatDateToMySQL(dados.data)}')`;
conn.query(sql, function (error){
if(error){
console.log('Houve um erro durante o INSERT', error);
return;
}
console.log('Dados inseridos com sucesso!');
});
Woooow, uma porção bem grande de códigos acabou de chegar, não é verdade?
Vamos ver com mais detalhes o que cada um dos comandos acima está fazendo 😉
const dados
é um objeto que representa as informações que queremos salvar na nossa base de dados. Essa parte é JS puro, ok? Se não compreendeu, você precisa voltar para a Jornada de Javascript.
formatDateToMySQL(date)
é uma função de apoio responsável por converter a data atual (new Date()
) para o formato DATETIME
, que é o formato da coluna data_criacao
.
Observação: Nem sempre você vai precisar da função formatDateToMySQL
em seus projetos. Só usamos ela ali, pois nossa tabela precisou receber uma data e hora em um formato diferenciado...
const sql
representa a sintaxe em SQL
da nossa inserção, note que estamos inserindo códigos do Javascript de forma direta dentro da query
(o que é um tipo de coisa insegura).
conn.query
é o método responsável por executar a query
que acabamos de criar, ou seja, inserir os dados no banco de dados.
Ela recebe dois parâmetros, o primeiro sempre será a query
, que no caso informamos a constante sql
, onde o segundo é o callback
com uma resposta de retorno.
Veja como ficou o index.js
com o código completo:
const mysql = require('mysql2');
//Cria a conexão com o banco de dados
const conn = mysql.createConnection({
host: 'localhost', //ou 127.0.0.1
user: 'root', //ou qualquer outro usuário que você tenha criado
password: '', //a senha relacionada ao usuário
database: 'nodejs', //o banco de dados que você criou
});
//Realiza a conexão com o banco de dados
conn.connect(function(error){
//Veririca se houve algum tipo de erro durante a conexão com o banco
if(error){
console.log('Houve um erro ao conectar com o banco', error);
return;
}
//Se estiver tudo OK, ele gera uma mensagem no console.
console.log('Conectado com o MySQL com sucesso!');
});
//Realiza a inserão de dados no banco de dados:
const dados = {
nome: 'Micilini Roll',
email: 'hey@micilini.com',
senha: 'MICILINI_É_DEZ',
data: new Date() // Data e hora atuais
};
// Função para formatar a data em 'YYYY-MM-DD HH:MM:SS'
function formatDateToMySQL(date) {
const pad = (n) => n < 10 ? '0' + n : n;
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
const sql = `INSERT INTO usuarios (nome, email, senha, data_criacao) VALUES ('${dados.nome}', '${dados.email}', '${dados.senha}', '${formatDateToMySQL(dados.data)}')`;
conn.query(sql, function (error){
if(error){
console.log('Houve um erro durante o INSERT', error);
return;
}
console.log('Dados inseridos com sucesso!');
});
Se tudo estiver OK, você receberá duas mensagens no console:
Para analisar se os dados foram realmente inseridos dentro da tabela, basta usar o MySQL WorkBench ou o HeidiSQL para isso.
Inserindo dados no banco de dados (seguro)
Apesar do código acima funcionar muito bem, a sua aplicação está totalmente vulnerável ao famoso SQL INJECTION.
E uma forma de resolver isso, é fazendo o uso de queries parametrizadas, da seguinte forma, observe:
//Realiza a inserão de dados no banco de dados:
const dados = {
nome: 'Micilini Roll',
email: 'hey@micilini.com',
senha: 'MICILINI_É_DEZ',
data: new Date()
};
// Função para formatar a data em 'YYYY-MM-DD HH:MM:SS'
function formatDateToMySQL(date) {
const pad = (n) => n < 10 ? '0' + n : n;
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
// Usando '?' para parametrizar os valores
const sql = `INSERT INTO usuarios (nome, email, senha, data_criacao) VALUES (?, ?, ?, ?)`;
conn.query(sql, [dados.nome, dados.email, dados.senha, formatDateToMySQL(dados.data)], function (error) {
if (error) {
console.log('Houve um erro durante o INSERT', error);
return;
}
console.log('Dados inseridos com sucesso!');
});
Observe que durante a declaração da nossa query
de insert
, usamos o ponto de interrogação (?
). Fizemos isso para que o método query
, fique com a parte da inserção de dados na tabela de forma segura (limpando os valores contra possíveis ataques de SQL INJECTION).
Note que dentro do segundo argumento do método query
, nós passamos cada um dos valores que serão inseridos, dentro de um array
.
Dessa forma, conseguimos manter a nossa aplicação mais segura contra o SQL INJECTION, por meio de queries parametrizadas.
Observação: A ordem dos valores que você for inserindo dentro do array
, segue a mesma ordem dos pontos de interrogação existentes dentro da nossa query
de INSERT
.
Recuperando dados no banco de dados
Para resgatar nossos dados que já estão inseridos no banco de dados, nós fazemos o uso da query SELECT
.
Observe como isso pode ser feito em conjunto com a tabela usuarios
:
//Realiza o SELECT na tabela de usuarios
const query = 'SELECT * FROM usuarios';
conn.query(query, function(error, results, fields){
if(error){
console.log('Houve um erro ao realizar a consulta', error);
return;
}
console.log('Resultado da consulta:', results);
});
No caso do comando acima, estamos retornando todos os dados existentes dentro da tabela usuarios
.
Mas caso desejar, você pode selecionar apenas registros específicos, e para isso, você deve pode usar o comando WHERE
dentro da query
da seguinte forma:
//Realiza o SELECT na tabela de usuarios
const query = 'SELECT * FROM usuarios WHERE id = 2';
conn.query(query, function(error, results, fields){
if(error){
console.log('Houve um erro ao realizar a consulta', error);
return;
}
console.log('Resultado da consulta:', results);
});
Entretanto, o comando acima, ainda é uma forma insegura de realizar consultas na nossa base de dados (mesmo o 'id = 2' sendo declarado de forma estática dentro da string).
Assim como vimos no INSERT
, nós também podemos fazer o uso de queries parametrizadas no nosso SELECT
, observe como isso pode ser feito:
//Realiza o SELECT na tabela de usuarios
const query = 'SELECT * FROM usuarios WHERE id = ?';
conn.query(query, [2], function(error, results, fields){
if(error){
console.log('Houve um erro ao realizar a consulta', error);
return;
}
console.log('Resultado da consulta:', results);
});
Note que usamos o ponto de interrogação dentro da query
, onde declaramos o valor atribuído dentro do segundo parâmetro do método query
.
Atualizando dados no banco de dados
O processo de atualização de uma determinada informação no banco de dados é bem simples, basta utilizarmos os comandos UPDATE
e WHERE
da seguinte forma:
//Realiza o UPDATE na tabela usuarios (inseguro)
const query = `UPDATE usuarios SET nome = 'Micilini Roll' WHERE id = 2`;
conn.query(query, function(error, results, fields){
if(error){
console.log('Houve um erro ao realizar a consulta', error);
return;
}
console.log('Resultado da consulta:', results);
});
Apesar do comando acima atualizar o nome do usuário perfeitamente, ele é considerado inseguro.
Sendo assim, o mais certo a se fazer é o uso do queries parametrizadas da seguinte forma:
//Realiza o UPDATE na tabela usuarios (seguro)
const query = `UPDATE usuarios SET nome = ? WHERE id = ?`;
conn.query(query, ['Micilini Roll', 2], function(error, results, fields){
if(error){
console.log('Houve um erro ao realizar a consulta', error);
return;
}
console.log('Resultado da consulta:', results);
});
Note que aqui também fizemos o uso do ponto de interrogação, onde declaramos o valor atribuído dentro do segundo parâmetro do método query
.
Observação: Nunca faça UPDATE
sem o WHERE
, pois você pode atualizar todos os registros da sua tabela do banco de dados de uma única vez 🫢
Removendo dados do banco de dados
A remoção de todos os dados (ou de apenas um dado no seu banco de dados), é feito por meio do comando DELETE
junto com o WHERE
.
Isso pode ser feito da seguinte forma:
//Realiza o DELETE na tabela usuarios (inseguro)
const query = `DELETE FROM usuarios WHERE id = 2`;
conn.query(query, function(error, results, fields){
if(error){
console.log('Houve um erro ao realizar a consulta', error);
return;
}
console.log('Resultado da consulta:', results);
});
Apesar do comando acima removendo usuario cujo o id
é igual a 2
, ele é considerado inseguro.
Sendo assim, o mais certo a se fazer, é o uso das queries parametrizadas da seguinte forma:
//Realiza o DELETE na tabela usuarios (seguro)
const query = `DELETE FROM usuarios WHERE id = ?`;
conn.query(query, [2], function(error, results, fields){
if(error){
console.log('Houve um erro ao realizar a consulta', error);
return;
}
console.log('Resultado da consulta:', results);
});
Observação: tenha muito cuidado ao realizar um DELETE
sem o WHERE
, pois você pode remover todos os registros da sua tabela do banco de dados 🫢
Otimizando suas conexões com o banco por meio do Connection Pool
Até o momento, nós aprendemos a criar conexões com o banco de dados, e realizar operações do tipo CRUD
(Create
, Read
, Update
e Delete
) dentro da nossa tabela de usuarios
.
Só que se você perceber, sempre quando realizamos uma operação no banco, nós estamos sempre fechando e abrindo conexões a todo momento:
//Realiza a conexão com o banco de dados
conn.connect(function(error){
//Veririca se houve algum tipo de erro durante a conexão com o banco
if(error){
console.log('Houve um erro ao conectar com o banco', error);
return;
}
//Se estiver tudo OK, ele gera uma mensagem no console.
console.log('Conectado com o MySQL com sucesso!');
});
Mas e se eu te falasse, que o driver do MySQL possui um mecanismo que é usado para gerenciar, e reutilizar conexões com o banco de dados de forma eficiente?
Sim, esse mecanismo é conhecido como o Connection Pool, e é responsável por manter um conjunto de conexões abertas que podem ser reutilizadas em qualquer outra parte da sua aplicação, o que melhora o desempenho da mesma 😉
No caso da biblioteca do mysql2
, o Connection Pool pode ser usado da seguinte forma:
const mysql = require('mysql2');
// Cria um pool de conexões
const pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'senha',
database: 'meu_banco',
waitForConnections: true,
connectionLimit: 10, // número máximo de conexões simultâneas
queueLimit: 0 // limite de solicitações na fila (0 significa ilimitado)
});
// Exemplo de como usar o pool
pool.query('SELECT * FROM minha_tabela', function (err, results) {
if (err) throw err;
console.log(results);
});
Este tipo de procedimento possui algumas vantagens, como:
- Evita o overhead de abrir e fechar conexões repetidamente.
- Melhora a escalabilidade, permitindo reutilizar conexões para múltiplas solicitações.
- Limita o número de conexões abertas, ajudando a prevenir sobrecarga no banco de dados.
Vejamos abaixo, um exemplo do uso do Connection Pool durante um INSERT
na tabela de usuarios:
const mysql = require('mysql2');
// Cria o pool de conexões
const pool = mysql.createPool({
host: 'localhost', // Endereço do servidor do banco de dados
user: 'root', // Usuário do banco de dados
password: '', // Senha do usuário
database: 'nodejs', // Nome do banco de dados
waitForConnections: true,
connectionLimit: 10, // Limita o número de conexões simultâneas
queueLimit: 0
});
// Função para formatar a data em 'YYYY-MM-DD HH:MM:SS'
function formatDateToMySQL(date) {
const pad = (n) => n < 10 ? '0' + n : n;
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
}
// Dados a serem inseridos
const dados = {
nome: 'Micilini Roll',
email: 'hey@micilini.com',
senha: 'MICILINI_É_DEZ',
data: new Date()
};
// Usando '?' para parametrizar os valores
const sql = `INSERT INTO usuarios (nome, email, senha, data_criacao) VALUES (?, ?, ?, ?)`;
// Conecta ao pool e realiza o INSERT
pool.getConnection((err, conn) => {
if (err) {
console.error('Houve um erro ao obter a conexão do pool', err);
return;
}
conn.query(sql, [dados.nome, dados.email, dados.senha, formatDateToMySQL(dados.data)], function (error) {
conn.release(); // Libera a conexão de volta ao pool após o uso
if (error) {
console.error('Houve um erro durante o INSERT', error);
return;
}
console.log('Dados inseridos com sucesso!');
});
});
Portando, podemos dizer que o Connection Pool cria uma especie de cache, permitindo a reutilização das querys que já foram executadas, tornando as respostas do seu servidor muito mais rápidas.
Dupla Interrogação VS Mono Interrogação?
Anteriormente, você viu que o uso do ponto de interrogação (?
), é usado para para substituir um único valor.
Se tornando extremamente útil quando você precisa substituir um único valor por posição, diretamente dentro da query
, por exemplo:
const sql = 'SELECT * FROM users WHERE id = ?';
connection.query(sql, ['2'], (error, results) => {
if (error) throw error;
console.log(results);
});
No exemplo acima, o valor 2
será substituído pelo ?
, o que faz com que nossa query
esteja segura contra SQL INJECTION.
Já a dupla interrogação (??
), é usada para substituir identificadores de banco de dados (como o nome de uma coluna ou tabela, por exemplo).
const sql = 'SELECT ?? FROM users';
connection.query(sql, ['username'], (error, results) => {
if (error) throw error;
console.log(results);
});
O ??
escapa automaticamente o identificador para evitar conflitos com nomes reservados ou caracteres especiais.
Mas será que nós podemos utilizar os dois juntos? Ou seja, dupla interrogação e mono interrogação dentro de uma mesma query?
Sim, observe o exemplo abaixo:
const sql = 'SELECT ?? FROM ?? WHERE id = ?';
const params = ['username', 'users', 2];
connection.query(sql, params, (error, results) => {
if (error) throw error;
console.log(results);
});
Incrível, não acha? 😋
Fechando conexões com o banco de dados
Sempre quando você executar uma query
(sem o uso do Connection Pool) é interessante fecharmos a conexão com o nosso banco de dados, para isso você pode utilizar o método end()
da seguinte forma:
const mysql = require('mysql2');
// Crie a conexão com o banco de dados
const connection = mysql.createConnection({
host: 'localhost',
user: 'seu_usuario',
password: 'sua_senha',
database: 'seu_banco_de_dados'
});
// Execute a query
connection.query('SELECT * FROM sua_tabela', (error, results, fields) => {
if (error) {
console.error('Erro ao executar a query:', error);
} else {
console.log('Resultados:', results);
}
// Feche a conexão
connection.end((err) => {
if (err) {
console.error('Erro ao fechar a conexão:', err);
} else {
console.log('Conexão encerrada com sucesso.');
}
});
});
Note que ele deve ser usado sempre após a execução da query
(ou seja, sempre no callback após a execução da query).
Isso garante que os recursos sejam liberados corretamente após o uso da conexão com o banco de dados, ou seja, sua aplicação não ficará consumindo memoria desnecessariamente 😅
Arquivos da lição
Os arquivos que você viu durante o decorrer desta lição, podem ser encontrados neste link.
Conclusão
Nesta lição, você aprendeu a se comunicar com o banco de dados, junto com as operações do tipo CRUD
(Create, Read, Update e Delete).
Na próxima lição, aprenderemos sobre o uso do Sequelize em suas aplicações feitas com NodeJS, até lá 😉