Aula: Banco de Dados com Node.js

Manipulação de Banco de Dados com Node.js

Do SQLite aos ORMs e NoSQL

Aula: Banco de Dados com Node.js

1. Introdução aos Bancos de Dados

Aula: Banco de Dados com Node.js

O que é um Banco de Dados?

É uma coleção organizada de dados, armazenada e acessada eletronicamente.

  • Persistência: Os dados não se perdem ao desligar a aplicação.
  • Gerenciamento: Permite criar, ler, atualizar e deletar dados de forma eficiente.
  • Segurança: Controla o acesso às informações.
Aula: Banco de Dados com Node.js

Bancos Relacionais (SQL)

  • Estrutura: Tabelas com linhas e colunas.
  • Esquema: Rígido, definido antes de inserir os dados.
  • Linguagem: SQL (Structured Query Language).
  • Garantia: Consistência (propriedades ACID).
  • Exemplos: PostgreSQL, MySQL, SQL Server, SQLite.
Aula: Banco de Dados com Node.js

Bancos Não Relacionais (NoSQL)

  • Estrutura: Flexível (documentos, chave-valor, etc.).
  • Esquema: Dinâmico ou inexistente.
  • Linguagem: APIs próprias de consulta.
  • Garantia: Alta performance e escalabilidade.
  • Exemplos: MongoDB, Redis, Cassandra, Neo4j.
Aula: Banco de Dados com Node.js

Por que SQLite?

  • Simples: Não precisa de um servidor. O banco é um único arquivo.
  • Leve: Fácil de configurar e usar.
  • Ideal para:
    • Aprendizado e estudos.
    • Prototipagem rápida.
    • Aplicações de pequeno e médio porte.
Aula: Banco de Dados com Node.js

2. Parte 1: sqlite3 no Node.js

(A forma "pura")

Aula: Banco de Dados com Node.js

Configuração do Ambiente

  1. Iniciar o projeto:
   mkdir node-sqlite-aula
   cd node-sqlite-aula
   npm init -y
Aula: Banco de Dados com Node.js
  1. Instalar o driver:
    npm install sqlite3
    
Aula: Banco de Dados com Node.js

Conectando e Criando a Tabela

// init-db.js
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('./database.db');

db.serialize(() => {
  db.run(`
    CREATE TABLE IF NOT EXISTS usuarios (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      nome TEXT NOT NULL,
      email TEXT NOT NULL UNIQUE
    )
  `);
  console.log('Tabela "usuarios" criada ou já existente.');
  db.close();
});

Para executar: node init-db.js

Aula: Banco de Dados com Node.js

Operações CRUD: Create (Criar)

// app.js
const db = require('./database.js');

const nome = 'Alice';
const email = 'alice@example.com';
const sql = `INSERT INTO usuarios (nome, email) VALUES (?, ?)`;

db.run(sql, [nome, email], function(err) {
  if (err) {
    return console.error(err.message);
  }
  console.log(`Usuário criado com o ID: ${this.lastID}`);
});
Aula: Banco de Dados com Node.js

Operações CRUD: Read (Ler)

const sql = `SELECT * FROM usuarios`;

db.all(sql, [], (err, rows) => {
  if (err) {
    return console.error(err.message);
  }
  console.log('Usuários cadastrados:');
  rows.forEach((row) => {
    console.log(`- ${row.id}: ${row.nome} (${row.email})`);
  });
});
Aula: Banco de Dados com Node.js

Operações CRUD: Update (Atualizar)

const novoNome = 'Alice Silva';
const id = 1;
const sql = `UPDATE usuarios SET nome = ? WHERE id = ?`;

db.run(sql, [novoNome, id], function(err) {
  if (err) {
    return console.error(err.message);
  }
  console.log(`Linhas afetadas: ${this.changes}`);
});
Aula: Banco de Dados com Node.js

Operações CRUD: Delete (Deletar)

const id = 2;
const sql = `DELETE FROM usuarios WHERE id = ?`;

db.run(sql, id, function(err) {
  if (err) {
    return console.error(err.message);
  }
  console.log(`Linhas afetadas: ${this.changes}`);
});
Aula: Banco de Dados com Node.js

3. O que são ORMs?

Object-Relational Mapping

Aula: Banco de Dados com Node.js

O Conceito de ORM

Um ORM é uma "ponte" que traduz o código que você escreve (objetos, classes) em comandos SQL que o banco de dados entende.

Você manipula objetos, o ORM manipula o SQL.

Objeto Usuario <--> ORM <--> Tabela usuarios

Aula: Banco de Dados com Node.js

Vantagens vs. Desvantagens

Vantagens 👍

  • Produtividade: Menos código SQL repetitivo.
  • Portabilidade: Troque de banco (SQLite -> PostgreSQL) com poucas alterações.
  • Segurança: Ajuda a prevenir SQL Injection.
  • Código mais legível e orientado a objetos.

Desvantagens 👎

  • Curva de Aprendizagem: É uma nova ferramenta para aprender.
  • Performance: Pode gerar SQL menos otimizado em casos complexos.
  • Abstração "vazada": Às vezes, você ainda precisa escrever SQL puro.
Aula: Banco de Dados com Node.js

4. ORM com Sequelize

Aula: Banco de Dados com Node.js
Sequelize: Instalação e Configuração
  1. Instalar pacotes:
    npm install sequelize sqlite3
    
  2. Configurar conexão:
    // sequelize.js
    const { Sequelize } = require('sequelize');
    
    const sequelize = new Sequelize({
      dialect: 'sqlite',
      storage: './database-sequelize.db'
    });
    
    module.exports = sequelize;
    
Aula: Banco de Dados com Node.js
Sequelize: Definindo um Modelo

Um "Modelo" representa uma tabela no banco.

// models/usuario.js
const { DataTypes } = require('sequelize');
const sequelize = require('../sequelize');

const Usuario = sequelize.define('Usuario', {
  nome: {
    type: DataTypes.STRING,
    allowNull: false
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true
  }
}, { tableName: 'usuarios' });

module.exports = Usuario;
Aula: Banco de Dados com Node.js

Sequelize: Sincronizando e Usando

O método .sync() cria a tabela se ela não existir.

Aula: Banco de Dados com Node.js
const sequelize = require('./sequelize');
const Usuario = require('./models/usuario');

async function main() {
  await sequelize.sync({ force: true }); // Cuidado em produção!

  // --- CREATE ---
  const user = await Usuario.create({ nome: 'Carlos', email: 'carlos@email.com' });

  // --- READ ---
  const usuarios = await Usuario.findAll();
  console.log(usuarios.map(u => u.toJSON()));

  // --- UPDATE ---
  await Usuario.update({ nome: 'Carlos Souza' }, { where: { id: 1 } });

  // --- DELETE ---
  await Usuario.destroy({ where: { id: 1 } });
}

main();
Aula: Banco de Dados com Node.js

5. ORM com Prisma

Aula: Banco de Dados com Node.js

Prisma: Uma abordagem moderna

Prisma não é um ORM tradicional. Ele usa um arquivo de schema para gerar um cliente de banco de dados otimizado e totalmente tipado.

  1. Instalação:
    npm install prisma --save-dev
    npm install @prisma/client
    
  2. Inicialização:
    npx prisma init --datasource-provider sqlite
    
    Isso cria a pasta prisma/ e o arquivo schema.prisma.
Aula: Banco de Dados com Node.js

Prisma: Definindo o Schema

Você descreve seus modelos no arquivo prisma/schema.prisma.

// prisma/schema.prisma
datasource db {
  provider = "sqlite"
  url      = "file:./database-prisma.db"
}

generator client {
  provider = "prisma-client-js"
}

model Usuario {
  id    Int     @id @default(autoincrement())
  email String  @unique
  nome  String? // ? = opcional
}
Aula: Banco de Dados com Node.js

Prisma: Migração e Geração

Com o schema definido, você aplica as mudanças no banco com migrate.

# Cria a migração e aplica no banco
npx prisma migrate dev --name init

Este comando:

  1. Salva a mudança do schema.
  2. Cria/atualiza o banco de dados.
  3. Gera o Prisma Client para você usar no código.
Aula: Banco de Dados com Node.js

Prisma: Operações CRUD

O código fica limpo, legível e seguro contra erros de digitação (com TS).

Aula: Banco de Dados com Node.js
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();

async function main() {
  // --- CREATE ---
  const user = await prisma.usuario.create({
    data: { nome: 'Fernanda', email: 'fernanda@email.com' },
  });

  // --- READ ---
  const usuarios = await prisma.usuario.findMany();

  // --- UPDATE ---
  await prisma.usuario.update({
    where: { email: 'fernanda@email.com' },
    data: { nome: 'Fernanda Lima' },
  });

  // --- DELETE ---
  await prisma.usuario.delete({ where: { id: 1 } });
}

main().finally(() => prisma.$disconnect());
Aula: Banco de Dados com Node.js

6. ORM com TypeORM

Aula: Banco de Dados com Node.js

TypeORM: Ideal para TypeScript

TypeORM utiliza Decorators para definir entidades, integrando-se perfeitamente com o sistema de tipos do TypeScript.

  1. Instalação:

    npm install typeorm sqlite3 reflect-metadata
    # E para o ambiente TS:
    npm install typescript ts-node @types/node --save-dev
    
  2. Configuração da Conexão (DataSource):
    É onde se define o tipo de banco, caminho e entidades.

Aula: Banco de Dados com Node.js

TypeORM: Definindo uma Entidade

Usa-se classes e decorators para mapear a tabela.

// src/entity/Usuario.ts
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity({ name: 'usuarios' }) // Mapeia para a tabela 'usuarios'
export class Usuario {

    @PrimaryGeneratedColumn()
    id: number;

    @Column()
    nome: string;

    @Column({ unique: true })
    email: string;
}
Aula: Banco de Dados com Node.js

TypeORM: Operações CRUD

As operações são feitas através de um "repositório" da entidade.

Aula: Banco de Dados com Node.js
import { AppDataSource } from "./data-source";
import { Usuario } from "./entity/Usuario";

AppDataSource.initialize().then(async () => {
    const repo = AppDataSource.getRepository(Usuario);

    // --- CREATE ---
    const user = new Usuario();
    user.nome = "Isabela";
    user.email = "isabela@email.com";
    await repo.save(user);

    // --- READ ---
    const usuarios = await repo.find();

    // --- UPDATE ---
    const userToUpdate = await repo.findOneBy({ id: 1 });
    if (userToUpdate) {
        userToUpdate.nome = "Isabela Rocha";
        await repo.save(userToUpdate);
    }
    // --- DELETE ---
    await repo.delete(1);
});
Aula: Banco de Dados com Node.js

7. Bancos Não Relacionais (NoSQL)

Um outro universo

Aula: Banco de Dados com Node.js

Principais Tipos de NoSQL

  • Documentos (MongoDB)

    • Armazena dados em JSON/BSON. Flexível e intuitivo.
    • { "nome": "João", "interesses": ["dev", "música"] }
  • Chave-Valor (Redis)

    • O mais simples: uma chave única aponta para um valor. Extremamente rápido.
    • "user:123": "{'nome':'Ana', 'sessao':'xyz'}"
Aula: Banco de Dados com Node.js
  • Coluna Larga (Cassandra)

    • Otimizado para consultas em massas de dados (Big Data, IoT).
  • Grafos (Neo4j)

    • Perfeito para dados com muitos relacionamentos (redes sociais, recomendações).
Aula: Banco de Dados com Node.js

Conclusão

Qual ferramenta usar?

  • sqlite3 (SQL Puro): Para entender os fundamentos ou para scripts simples onde performance total é crítica.
  • Sequelize: Um ORM tradicional, maduro e com grande ecossistema. Ótimo para projetos legados ou quem prefere o padrão Active Record.
  • Prisma: Moderno, focado em DX (Developer Experience) e segurança de tipos. Excelente para novos projetos, especialmente com TypeScript.
  • TypeORM: A escolha natural para projetos robustos em TypeScript, usando decorators para uma integração profunda.

Não existe "o melhor", existe o mais adequado para o seu problema!

Aula: Banco de Dados com Node.js

Perguntas?