Integrando ao

Banco de Dados

Capacidade de Conexão

 

Conectar à banco de dados em aplicativos do Express é apenas uma questão de se carregar um driver Node.js apropriado para o banco de dados no seu aplicativo.

npm install mysql2
// ou
yarn add mysql2

Instalação do Driver

ORM

 

(Object Relational Mapper) é uma técnica de mapeamento objeto relacional que permite fazer uma relação dos objetos com os dados que os mesmos representam.

Sequelize

Sequelize

 

Sequelize é um ORM baseado em promises para Postgres, MySQL, MariaDB, SQLite e Microsoft SQL Server.

Possui suporte sólido de transações, relações, replicação de leitura e muito mais.

npm install sequelize
// ou
yarn add sequelize

Instalação

const { Sequelize } = require('sequelize');
const bd = {};

const options = {
  username: 'admin',
  password: 'notes123',
  database: 'notes',
  host: 'notes.cgssmrnlwpdu.us-east-2.rds.amazonaws.com',
  dialect: 'mysql',
};

const sequelize = new Sequelize(options);
sequelize
  .authenticate()
  .then(() => console.log(`Conectado com sucesso ao banco ${options.database}`))
  .catch((err) => console.log(`Falha ao conectar ao banco ${options.database}: ${err}`));

bd.sequelize = sequelize;
bd.Sequelize = Sequelize;

module.exports = bd;

Conexão

Desafio

 

Após instalar o mysql e configurá-lo em seu ambiente de desenvolvimento, realize a conexão da sua aplicação Node.js.

Tabelas

 

O próximo passo é criar nossas tabelas, usando o script dos objetos do banco

Criação de Modelos

Modelos

 

Modelos são a essência do Sequelize. São abstrações que representam as tabelas do banco de dados.

Os modelos dizem ao Sequelize informações importantes como nome da tabela e seus atributos.

Um modelo possui um nome, que não necessita ser o mesmo da tabela.

Modelo

module.exports = (sequelize, DataTypes) => {
  const Usuario = sequelize.define(
    'usuario',
    {
      id: {
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true
      },
      nome: {
        type: DataTypes.STRING,
        allowNull: false
      },
      email: {
        type: DataTypes.STRING,
        allowNull: false
      },
      senha: {
        type: DataTypes.STRING,
        allowNull: false
      }
    },
    {
      tableName: 'usuario',
      timestamps: false
    }
  );
  
  return Usuario;
};

Sequelize Auto

Carregando os Modelos

const { Sequelize, DataTypes } = require('sequelize');
let _Checklist = require('./checklist');
let _Nota = require('./nota');
let _Usuario = require('./usuario');
const db = {};

//..

const sequelize = new Sequelize(options);

//..

const Checklist = _Checklist(sequelize, DataTypes);
const Nota = _Nota(sequelize, DataTypes);
const Usuario = _Usuario(sequelize, DataTypes);

db = { Checklist, Nota, Tag, Usuario };

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

Associações


As associações permitem acesso a objetos relacionados a outros em um banco de dados.

São 4 tipos de associações disponíveis no Sequelize:

  • HasOne;

  • BelongsTo;

  • HasMany;

  • BelongsToMany.

[
  {
    "id": 1,
    "titulo": "Teste",
    "descricao": null,
    "usuarioId": 1,
    "usuario": {
      "id": 1,
      "nome": "Alan",
      "email": "alansantos@grupointegrado.br"
    }
  }
]

Dado Associado

[
  {
    "id": 1,
    "nome": "Alan",
    "email": "alansantos@grupointegrado.br",
    "notas": [
      {
        "id": 1
      },
      {
        "id": 2
      }
    ]
  }
]

Dado Associado

HasMany

const Checklist = inicializarChecklist(sequelize, DataTypes);
const Nota = inicializarNota(sequelize, DataTypes);

Nota.hasMany(Checklist, { as: 'checklists', foreignKey: 'notaId' });

BelongsTo

const Usuario = _Usuario(sequelize, DataTypes);
const Nota = _Nota(sequelize, DataTypes);

Nota.belongsTo(Usuario, { as: 'usuario', foreignKey: 'usuarioId' });

Operações Básicas

await Usuario.create({
  nome: "Alan",
  email: "alansantos@grupointegrado.br"
});

let user = await Usuario.findOrCreate({
  defaults: {
    nome: "Alan",
  	email: "alansantos@grupointegrado.br"
  },
  where: {
    email: "alansantos@grupointegrado.br"
  }
});

console.log(user.isNewRecord);

Create

await Usuario.update({
  nome: "Alan",
  email: "alansantos@grupointegrado.br"
}, {
  where: {
    id
  }
});

Update

await Usuario.destroy({
  where: {
    id
  }
});

Destroy

await Usuario.findAll();

await Usuario.findAll({
  where: {
    id
  }
});

await Usuario.findAll({
  attributes: ['id', 'nome', 'email', 'avatar'],
  where: {
    id
  }
});

Consultas

const { Nota, Checklist, conexao } = require('../bd');
const transaction = await sequelize.transaction();

try {
  await Nota.create(nota, {
    transaction
  });
  
  await Checklist.create(checklist, {
    transaction
  });

  await transaction.commit();
} catch (error) {
  await transaction.rollback();
  
  //tratar status da requisição
}

Transações

Desafio

Para as rotas criadas em seu projeto, criar controllers para cada recurso:

  • DELETE;

  • PUT;

  • A rota PUT deve receber um id.

  • Adicionar try/catch em todas as rotas e tratar o status de resposta caso ocorra um erro (500);

await Nota.findAll({
  where: {
    id
  },
  include: [
    {
      model: Usuario
    }
  ]
});

Consultas Associativas

Rodando APIs em ambientes
diferentes

Ambientes diversificados

 

É comum aplicações possuírem diversos ambientes como os ambientes de desenvolvimento, homologação, testes, etc. É indicado que esses ambientes possuam bancos de dados isolados para melhorar o controle de dados.

Ambientes diversificados

 

Para facilitar essas conexões, centralizaremos os dados de conexão da nossa aplicação.

{
  "username": "admin",
  "password": "notes123",
  "database": "notes",
  "dialect": "mysql",
  "host": "notes.cgssmrnlwpdu.us-east-2.rds.amazonaws.com",
}

Criando um arquivo JSON

const { Sequelize, DataTypes } = require('sequelize');
const database = require('../config/database.json');

// ...

const sequelize = new Sequelize(database);

Carregando as Configurações

Variáveis de Ambiente

Variáveis de Ambiente

 

São um valores nomeados dinamicamente que podem afetar o modo como os processos em execução irão se comportar em um computador

{
  "development": {
    "username": "admin",
    "password": "notes123",
    "database": "notes",
    "dialect": "mysql",
    "host": "notes.cgssmrnlwpdu.us-east-2.rds.amazonaws.com",
  },
  "production": {
    "username": "admin",
    "password": "notes123",
    "database": "notes",
    "dialect": "mysql",
    "host": "notes.cgssmrnlwpdu.us-east-2.rds.amazonaws.com",
  }
}

Possibilidades

npm install --save-dev cross-env
// ou
yarn add -D cross-env

Pacote cross-env

{
  "scripts": {
    "serverprod": "cross-env NODE_ENV=production nodemon app.js",
    "serverdev": "cross-env NODE_ENV=development nodemon app.js",
    "start": "nodemon app.js"
  }
}

Utilizando no package.json

const { Sequelize, DataTypes } = require('sequelize');
const database = require('../config/database.json');
const env = process.env.NODE_ENV || 'production';

// ...

const sequelize = new Sequelize(database[env]);

Carregando as Configurações

Integração com Banco de Dados

By Alan Ferreira dos Santos

Integração com Banco de Dados

  • 407