{"id":2061,"date":"2026-06-22T14:10:43","date_gmt":"2026-06-22T17:10:43","guid":{"rendered":"https:\/\/desvendandoocodigo.com.br\/?p=2061"},"modified":"2026-06-22T14:11:30","modified_gmt":"2026-06-22T17:11:30","slug":"como-salvar-dados-no-mysql-com-node-js-projeto-real-de-barbearia","status":"publish","type":"post","link":"https:\/\/desvendandoocodigo.com.br\/?p=2061","title":{"rendered":"Como Salvar Dados no MySQL com Node.js | Projeto Real de Barbearia"},"content":{"rendered":"\n<p>Uma das d\u00favidas mais comuns de quem est\u00e1 aprendendo desenvolvimento web \u00e9:<\/p>\n\n\n\n<p><strong>&#8220;Como os dados de um formul\u00e1rio chegam at\u00e9 o banco de dados?&#8221;<\/strong><\/p>\n\n\n\n<p>Neste projeto vamos construir um sistema de agendamento para uma barbearia utilizando:<\/p>\n\n\n\n<ul>\n<li>HTML;<\/li>\n\n\n\n<li>CSS;<\/li>\n\n\n\n<li>JavaScript;<\/li>\n\n\n\n<li>Node.js;<\/li>\n\n\n\n<li>Express;<\/li>\n\n\n\n<li>MySQL.<\/li>\n<\/ul>\n\n\n\n<p>Ao final, os dados digitados pelo usu\u00e1rio ser\u00e3o enviados para o backend e gravados no banco de dados.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83c\udfa5 V\u00eddeo editado<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Como Salvar Dados no MySQL com Node.js | Projeto Real de Barbearia<\/h2>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Como Salvar Dados no MySQL com Node.js | Projeto Real de Barbearia\" width=\"960\" height=\"540\" src=\"https:\/\/www.youtube.com\/embed\/ypyvc6RMaoo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udcfa Live completa<\/h1>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Mini Projeto: Sistema de Barbearia com Node.js e MySQL (Salvando Agendamentos)\" width=\"960\" height=\"540\" src=\"https:\/\/www.youtube.com\/embed\/Fu_miolJ2z4?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">O projeto<\/h1>\n\n\n\n<p>O objetivo \u00e9 criar um sistema simples de agendamento.<\/p>\n\n\n\n<p>O usu\u00e1rio informa:<\/p>\n\n\n\n<ul>\n<li>Nome;<\/li>\n\n\n\n<li>Procedimento;<\/li>\n\n\n\n<li>Data;<\/li>\n\n\n\n<li>Hor\u00e1rio.<\/li>\n<\/ul>\n\n\n\n<p>Essas informa\u00e7\u00f5es ser\u00e3o enviadas para o backend e gravadas no MySQL.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Criando o banco de dados<\/h1>\n\n\n\n<p>Primeiro criamos o banco:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE DATABASE agendamento;\n<\/code><\/pre>\n\n\n\n<p>Depois criamos a tabela:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE TABLE agendamentos (\n    id INT AUTO_INCREMENT PRIMARY KEY,\n    nome VARCHAR(100),\n    procedimento VARCHAR(100),\n    dia DATE,\n    hora TIME,\n    criado_em TIMESTAMP DEFAULT CURRENT_TIMESTAMP\n);\n<\/code><\/pre>\n\n\n\n<p>O campo TIMESTAMP funciona como um carimbo de data e hora.<\/p>\n\n\n\n<p>Isso \u00e9 muito \u00fatil para auditoria e hist\u00f3rico.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Instalando os pacotes<\/h1>\n\n\n\n<p>O backend utiliza:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install express mysql2\n<\/code><\/pre>\n\n\n\n<p>Esses dois pacotes s\u00e3o suficientes para fazer a comunica\u00e7\u00e3o com o MySQL.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Configurando o Express<\/h1>\n\n\n\n<p>Criamos a aplica\u00e7\u00e3o:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const app = express();\n<\/code><\/pre>\n\n\n\n<p>E configuramos os middlewares:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.use(express.json());\napp.use(express.static(\"public\"));\n<\/code><\/pre>\n\n\n\n<p>Assim conseguimos:<\/p>\n\n\n\n<ul>\n<li>receber JSON;<\/li>\n\n\n\n<li>servir os arquivos do frontend.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Configurando a conex\u00e3o com o banco<\/h1>\n\n\n\n<p>Criamos um objeto com as configura\u00e7\u00f5es:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const dbConfig = {\n    host: \"localhost\",\n    user: \"root\",\n    password: \"senha\",\n    database: \"agendamento\"\n};\n<\/code><\/pre>\n\n\n\n<p>Em projetos profissionais \u00e9 recomend\u00e1vel utilizar vari\u00e1veis de ambiente (.env).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Criando a rota POST<\/h1>\n\n\n\n<p>A rota respons\u00e1vel por salvar os dados:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.post(\"\/salvar-agendamento\", async (req, res) =&gt; {\n});\n<\/code><\/pre>\n\n\n\n<p>Como trabalhamos com banco de dados, utilizamos fun\u00e7\u00f5es ass\u00edncronas.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Utilizando Try, Catch e Finally<\/h1>\n\n\n\n<p>Uma boa pr\u00e1tica \u00e9 tratar erros:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>try {\n\n}\ncatch(error){\n\n}\nfinally{\n\n}\n<\/code><\/pre>\n\n\n\n<p>Isso permite:<\/p>\n\n\n\n<ul>\n<li>identificar problemas;<\/li>\n\n\n\n<li>registrar erros;<\/li>\n\n\n\n<li>fechar conex\u00f5es corretamente.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Recuperando os dados enviados<\/h1>\n\n\n\n<p>Os dados chegam atrav\u00e9s do body da requisi\u00e7\u00e3o:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const {\n    nome,\n    procedimento,\n    dia,\n    hora\n} = req.body;\n<\/code><\/pre>\n\n\n\n<p>Essa t\u00e9cnica \u00e9 chamada de desestrutura\u00e7\u00e3o.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Criando a query SQL<\/h1>\n\n\n\n<p>Montamos a instru\u00e7\u00e3o SQL:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>INSERT INTO agendamentos\n(nome, procedimento, dia, hora)\nVALUES (?, ?, ?, ?)\n<\/code><\/pre>\n\n\n\n<p>Os pontos de interroga\u00e7\u00e3o s\u00e3o importantes para evitar SQL Injection.<\/p>\n\n\n\n<p>Essa abordagem utiliza Prepared Statement e aumenta a seguran\u00e7a da aplica\u00e7\u00e3o.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Executando o INSERT<\/h1>\n\n\n\n<p>A execu\u00e7\u00e3o acontece atrav\u00e9s do m\u00e9todo:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>connection.execute()\n<\/code><\/pre>\n\n\n\n<p>Depois do INSERT podemos recuperar:<\/p>\n\n\n\n<ul>\n<li>id gerado;<\/li>\n\n\n\n<li>quantidade de linhas afetadas;<\/li>\n\n\n\n<li>resultado da opera\u00e7\u00e3o.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Testando com Hoppscotch e Postman<\/h1>\n\n\n\n<p>Antes do frontend, testamos a API.<\/p>\n\n\n\n<p>Ferramentas \u00fateis:<\/p>\n\n\n\n<ul>\n<li>Postman;<\/li>\n\n\n\n<li>Thunder Client;<\/li>\n\n\n\n<li>Insomnia;<\/li>\n\n\n\n<li>Hoppscotch.<\/li>\n<\/ul>\n\n\n\n<p>Isso facilita a depura\u00e7\u00e3o e permite testar as rotas isoladamente.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Corrigindo erros faz parte do processo<\/h1>\n\n\n\n<p>Durante o desenvolvimento apareceu um erro:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>nome n\u00e3o est\u00e1 definido\n<\/code><\/pre>\n\n\n\n<p>O problema aconteceu porque os dados ainda n\u00e3o estavam sendo recuperados do req.body.<\/p>\n\n\n\n<p>Ap\u00f3s fazer:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const { nome, procedimento, dia, hora } = req.body;\n<\/code><\/pre>\n\n\n\n<p>Tudo passou a funcionar.<\/p>\n\n\n\n<p>Programar \u00e9 isso:<\/p>\n\n\n\n<ul>\n<li>testar;<\/li>\n\n\n\n<li>errar;<\/li>\n\n\n\n<li>corrigir;<\/li>\n\n\n\n<li>continuar.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Criando a rota GET<\/h1>\n\n\n\n<p>Tamb\u00e9m criamos uma rota para listar os dados:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>app.get(\"\/listar-agendamentos\")\n<\/code><\/pre>\n\n\n\n<p>Com ela conseguimos consultar tudo que foi salvo no banco.<\/p>\n\n\n\n<p>A consulta SQL utilizada foi:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT * FROM agendamentos\n<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Integrando com o Frontend<\/h1>\n\n\n\n<p>Depois do backend pronto, fizemos a integra\u00e7\u00e3o utilizando Fetch API.<\/p>\n\n\n\n<p>O formul\u00e1rio captura:<\/p>\n\n\n\n<ul>\n<li>nome;<\/li>\n\n\n\n<li>procedimento;<\/li>\n\n\n\n<li>data;<\/li>\n\n\n\n<li>hor\u00e1rio.<\/li>\n<\/ul>\n\n\n\n<p>E envia para o servidor.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>fetch()\n<\/code><\/pre>\n\n\n\n<p>Essa \u00e9 a ponte entre frontend e backend.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Salvando os dados no MySQL<\/h1>\n\n\n\n<p>Ap\u00f3s enviar o formul\u00e1rio:<\/p>\n\n\n\n<ol>\n<li>O navegador envia os dados.<\/li>\n\n\n\n<li>O Express recebe a requisi\u00e7\u00e3o.<\/li>\n\n\n\n<li>O Node.js executa o SQL.<\/li>\n\n\n\n<li>O MySQL grava as informa\u00e7\u00f5es.<\/li>\n<\/ol>\n\n\n\n<p>Finalmente o sistema retorna uma mensagem para o usu\u00e1rio.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">O que voc\u00ea aprendeu<\/h1>\n\n\n\n<p>Neste projeto voc\u00ea viu:<\/p>\n\n\n\n<p>\u2705 Node.js<\/p>\n\n\n\n<p>\u2705 Express<\/p>\n\n\n\n<p>\u2705 MySQL<\/p>\n\n\n\n<p>\u2705 SQL<\/p>\n\n\n\n<p>\u2705 Rotas POST<\/p>\n\n\n\n<p>\u2705 Rotas GET<\/p>\n\n\n\n<p>\u2705 Async\/Await<\/p>\n\n\n\n<p>\u2705 Try\/Catch\/Finally<\/p>\n\n\n\n<p>\u2705 Prepared Statements<\/p>\n\n\n\n<p>\u2705 req.body<\/p>\n\n\n\n<p>\u2705 Fetch API<\/p>\n\n\n\n<p>\u2705 Integra\u00e7\u00e3o Frontend + Backend<\/p>\n\n\n\n<p>\u2705 Persist\u00eancia no banco de dados<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Conclus\u00e3o<\/h1>\n\n\n\n<p>Esse projeto de barbearia \u00e9 um excelente exemplo de aplica\u00e7\u00e3o Full Stack.<\/p>\n\n\n\n<p>Ele mostra como HTML, JavaScript, Node.js e MySQL trabalham juntos para construir sistemas reais.<\/p>\n\n\n\n<p>E o mais importante:<\/p>\n\n\n\n<p>Programar n\u00e3o \u00e9 decorar c\u00f3digo.<\/p>\n\n\n\n<p>\u00c9 entender como as tecnologias se comunicam.<\/p>\n\n\n\n<p>Porque quando voc\u00ea entende o fluxo:<\/p>\n\n\n\n<p>Frontend \u2192 Backend \u2192 Banco de Dados<\/p>\n\n\n\n<p>Voc\u00ea come\u00e7a a enxergar como aplica\u00e7\u00f5es reais s\u00e3o constru\u00eddas.<\/p>\n\n\n\n<p><strong>Eu n\u00e3o ensino programa\u00e7\u00e3o.<\/strong><\/p>\n\n\n\n<p><strong>Eu ajudo as pessoas a entenderem como a tecnologia funciona.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Uma das d\u00favidas mais comuns de quem est\u00e1 aprendendo desenvolvimento web \u00e9: &#8220;Como os dados de um formul\u00e1rio chegam at\u00e9 o banco de dados?&#8221; Neste projeto vamos construir um sistema de agendamento para uma barbearia utilizando: Ao final, os dados digitados pelo usu\u00e1rio ser\u00e3o enviados para o backend e gravados no banco de dados. \ud83c\udfa5 V\u00eddeo editado Como Salvar Dados no MySQL com Node.js | Projeto Real de Barbearia \ud83d\udcfa Live completa O projeto O objetivo \u00e9 criar um sistema simples de agendamento. O usu\u00e1rio informa: Essas informa\u00e7\u00f5es ser\u00e3o enviadas para o backend e gravadas no MySQL. Criando o banco de dados Primeiro criamos o banco: Depois criamos a tabela: O campo TIMESTAMP funciona como um carimbo de data e hora. Isso \u00e9 muito \u00fatil para auditoria e hist\u00f3rico. Instalando os pacotes O backend utiliza: Esses dois pacotes s\u00e3o suficientes para fazer a comunica\u00e7\u00e3o com o MySQL. Configurando o Express Criamos a aplica\u00e7\u00e3o: E configuramos os middlewares: Assim conseguimos: Configurando a conex\u00e3o com o banco Criamos um objeto com as configura\u00e7\u00f5es: Em projetos profissionais \u00e9 recomend\u00e1vel utilizar vari\u00e1veis de ambiente (.env). Criando a rota POST A rota respons\u00e1vel por salvar os dados: Como trabalhamos com banco de dados, utilizamos fun\u00e7\u00f5es ass\u00edncronas. Utilizando Try, Catch e Finally Uma boa pr\u00e1tica \u00e9 tratar erros: Isso permite: Recuperando os dados enviados Os dados chegam atrav\u00e9s do body da requisi\u00e7\u00e3o: Essa t\u00e9cnica \u00e9 chamada de desestrutura\u00e7\u00e3o. Criando a query SQL Montamos a instru\u00e7\u00e3o SQL: Os pontos de interroga\u00e7\u00e3o s\u00e3o importantes para evitar SQL Injection. Essa abordagem utiliza Prepared Statement e aumenta a seguran\u00e7a da aplica\u00e7\u00e3o. Executando o INSERT A execu\u00e7\u00e3o acontece atrav\u00e9s do m\u00e9todo: Depois do INSERT podemos recuperar: Testando com Hoppscotch e Postman Antes do frontend, testamos a API. Ferramentas \u00fateis: Isso facilita a depura\u00e7\u00e3o e permite testar as rotas isoladamente. Corrigindo erros faz parte do processo Durante o desenvolvimento apareceu um erro: O problema aconteceu porque os dados ainda n\u00e3o estavam sendo recuperados do req.body. Ap\u00f3s fazer: Tudo passou a funcionar. Programar \u00e9 isso: Criando a rota GET Tamb\u00e9m criamos uma rota para listar os dados: Com ela conseguimos consultar tudo que foi salvo no banco. A consulta SQL utilizada foi: Integrando com o Frontend Depois do backend pronto, fizemos a integra\u00e7\u00e3o utilizando Fetch API. O formul\u00e1rio captura: E envia para o servidor. Essa \u00e9 a ponte entre frontend e backend. Salvando os dados no MySQL Ap\u00f3s enviar o formul\u00e1rio: Finalmente o sistema retorna uma mensagem para o usu\u00e1rio. O que voc\u00ea aprendeu Neste projeto voc\u00ea viu: \u2705 Node.js \u2705 Express \u2705 MySQL \u2705 SQL \u2705 Rotas POST \u2705 Rotas GET \u2705 Async\/Await \u2705 Try\/Catch\/Finally \u2705 Prepared Statements \u2705 req.body \u2705 Fetch API \u2705 Integra\u00e7\u00e3o Frontend + Backend \u2705 Persist\u00eancia no banco de dados Conclus\u00e3o Esse projeto de barbearia \u00e9 um excelente exemplo de aplica\u00e7\u00e3o Full Stack. Ele mostra como HTML, JavaScript, Node.js e MySQL trabalham juntos para construir sistemas reais. E o mais importante: Programar n\u00e3o \u00e9 decorar c\u00f3digo. \u00c9 entender como as tecnologias se comunicam. Porque quando voc\u00ea entende o fluxo: Frontend \u2192 Backend \u2192 Banco de Dados Voc\u00ea come\u00e7a a enxergar como aplica\u00e7\u00f5es reais s\u00e3o constru\u00eddas. Eu n\u00e3o ensino programa\u00e7\u00e3o. Eu ajudo as pessoas a entenderem como a tecnologia funciona.<\/p>\n","protected":false},"author":1,"featured_media":2062,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2061"}],"collection":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2061"}],"version-history":[{"count":3,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2061\/revisions"}],"predecessor-version":[{"id":2065,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/posts\/2061\/revisions\/2065"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=\/wp\/v2\/media\/2062"}],"wp:attachment":[{"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2061"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2061"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/desvendandoocodigo.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2061"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}