Multi-banco de dados em aplicações Laravel
Tags: laravel, beginners, php, database
Published: 2022-08-16 20:45:35

## Apresentação

Neste post vamos configurar dois bancos de dados na mesma aplicação Laravel:
* [SQLite](https://www.sqlite.org/index.html): banco de dados em arqtuivo
* [MySQL](https://www.sqlite.org/index.html): SGBD que dispensa apresentações

A ideia é que o projeto seja pequeno, apenas com o essencial para atingirmos o que está sendo proposto.

Entretanto, convém alertar que conhecimento prévio no framework Laravel é essencial, mais por conta de saber como se localizar dentro da aplicação do que pela linguagem PHP propriamente dita.

Conhecimento de banco de dados não é essencial mas se tiver, melhor.

---

Este artigo foi dividido em etapas de forma que você possa ir direto para cada uma delas caso se sinta confortável ou já tenha realizado atividades semelhantes.

[O que você precisa para executar este projeto](#what_do_u_need)
Esta etapa traz os programas necessários para acompanhar este artigo.

[Ambiente](#environment)
Esta etapa mostra como o ambiente deve estar configurado.

[Projeto](#project)
Esta etapa é a maior. Vamos criar e configurar o projeto para alcançar o objetivo proposto.

[Execução](#executing)
Aqui vamos executar o projeto verificando o resultado.

[Conclusão](#conclusion)

---

## O que você precisa para executar este projeto <a name="what_do_u_need"></a>

> PHP

No momento em que escrevo este artigo o [PHP](https://www.php.net/) está na sua versão 8.1.

Criado em 1994 por Rasmus Lerdorf, teve sua primeira versão liberada somente em 1995 como um pacote de programas CGI.

Atualmente é mantido pelo PHP Group.

---

> Composer

Até meados da década de 1990, era comum o desenvolvedor criar 'na mão' rotinas auxiliares para a aplicação principal, como conectar com bancos de dados por exemplo.

Entretanto, com a popularização da internet muitas dessas rotinas foram parar em repositórios mantidos por desenvolvedores do mundo todo.

E para facilitar a pesquisa e uso dessas rotinas surgiram os gerenciadores de dependências.

Por exemplo, para c# há o [Nuget](https://www.nuget.org/); para  JavaScript temos o [NPM](https://www.npmjs.com/).

E no PHP existe o [Composer](https://getcomposer.org/).

O repositório acessado pelo Composer é o [Packagist](https://packagist.org/).

A partir da versão 9 do Laravel recomenda-se que seja utilizado o PHP 8 ou superior.

---

> MySQL

De acordo com a pesquisa anual [Stack Overflow Developer Survey 2002](
https://dev.to/marciopolicarpo/stack-overflow-developer-survey-2022-na4), o [MySQL Server](https://www.mysql.com/downloads/) foi o banco de dados escolhido por mais de 46% do total de respostas e foi citado por 58% das pessoas que estão aprendendo a desenvolver.

Se você se sentir confortável, sugiro instalar individualmente tanto o PHP quando o MySQL.

Se este não for o seu caso, existem pacotes que facilitam a instalação do PHP e MySQL, além de trazer também o Apache como servidor web.

---

> SQLite

Este é um banco de dados pequeno, independente e desenvolvido em C.

Devido à sua versatilidade ele é largamente utilizado em smartphones.

Por conter toda lógica de SQL em um único arquivo físico ele também é usado como "cache" de outras aplicações com o objetivo de reduzir tráfego de rede e processos de I/O em servidores.

---

> Gerenciador de banco de dados

A depender de como a instalação do MySQL foi feita você terá acesso ao banco de dados através do navegador de internet padrão com o PHPMyAdmin.

Entretanto, sugiro a utilização de um gerenciador de banco de dados, como por exemplo [DBeaver](https://dbeaver.io/).

Ele é gratuito e se conecta em quase todos os SGBDs disponíveis na atualidade.

---

> Editor de textos

Há opções para todos os gostos e sistemas operacionais.

Estou utilizando [Visual Studio Code](https://code.visualstudio.com/download).

Além de ser gratuito, possibilita a instalação de diversas extensões.

---

## Ambiente <a name="environment"></a>

> PHP

Antes de iniciarmos o projeto é necessário fazer uma pequena alteração no arquivo de configuração do PHP.

O local do arquivo _php.ini_ vai depender de como a instalação foi realizada.

Utilizando o editor de textos de sua preferência abra o arquivo _php.ini_ e localize a seção **Dynamic Extensions**.

Dentro dessa seção navegue até a seguinte linha ...

```php
;extension=pdo_sqlite
```

... e remova o 'ponto-e-vírgula' do início, salvando o arquivo em seguida.

---

> MySQL <a name="mysql_config"></a>

A ação seguinte pode ser feita através do console do MySQL, pelo gerenciador de banco de dados ou pelo PHPMyAdmin, caso você tenha instalado o MySQL através de um pacote como XAMP ou WAMP.

Acessando o servidor do MySQL crie um banco de dados identificado como 'laravel'.

Informe outro caso este nome já esteja em uso.

Este nome deve ser colocado na variável 'DB_DATABASE' do arquivo ['.env'](#env_file) que veremos mais à frente.

---

## Projeto <a name="project"></a>

> Criação

Abra o terminal de sua preferência, acesse a pasta que servirá de ponto de partida para o projeto e digite o seguinte comando:

```php
composer create-project laravel/laravel multi-database
```

O tempo para conclusão desta etapa pode variar de acordo com a conexão à internet e configuração do computador.

---

Ainda no terminal acesse o diretório raiz do projeto criado e digite o seguinte comando: <a name="create_model"></a>

```php
php artisan make:model Movie -mf
```

A finalidade deste comando é criar um modelo objeto relacional (model) para guardarmos uma lista de filmes.

Os parâmetros opcionais '-mf' vão orientar o `artisan` a criar também a migração ('m') e uma classe `factory `('f'), economizando tempo.

---

> Arquivo _database.php_

Este arquivo guarda os detalhes de conexão com bancos de dados e faremos uma pequena alteração nele.

Na seção _Database Connections_ localize o nó `sqlite` e nele, altere a propriedade `database` de ...

```php
'database' => env('DB_DATABASE', database_path('database.sqlite'))
```

para 

```php
'database' => env('', database_path('database.sqlite'))
```

Esta mudança é necessária porque o SQLite não possui um nome de banco de dados.

---

> Arquivo _.env_ <a name="env_file"></a>

Este arquivo se encontra no diretório raiz da aplicação e faremos uma pequena modificação para conectar ao MySQL.

Com o arquivo no editor, localize as variáveis iniciadas com `DB_` e altere os valores para ficar de acordo com a configuração feita na instalação do MySQL:

```php
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
```

onde:

- DB_DATABASE: nome do banco de dados configurado [aqui](#mysql_config)
- DB_USERNAME: usuário do banco de dados (geralmente _root_)
- DB_PASSWORD: senha do banco de dados

Salve e feche este arquivo.

---

> Migração

No arquivo de migração que foi criado [nesta etapa](#create_model) vamos incluir uma propriedade protegida chamada `$connection` que receberá o nome da conexão utilizada pela migração desta tabela:

```php
protected $connection = 'sqlite';
```

E para finalizar as alterações neste arquivo de migração, vamos colocar duas colunas (title, imdb_rating) no método `up()`:

```php
public function up()
{
    Schema::create('movies', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->string('title');
        $table->decimal('imdb_rating');
    });
}
```

---

> Modelo

Na classe _\app\Models\Movie.php_ vamos adicionar somente a propriedade que configura o nome da conexão no modelo:

```php
protected $connection = 'sqlite';
```

---

> Seed

Utilizando o facilitador para criar registros aleatórios vamos editar a classe _\database\factories\MovieFactory.php_ criada [nesta etapa](#create_model) e alterar o método ´definition()´ ficando como mostrado a seguir:

```php
public function definition()
{
    return [
        'title' => fake()->word(),
        'imdb_rating' => fake()->randomFloat(1, 1, 10)
    ];
}
```

---

Em seguida vamos editar a classe _\database\seeders\DatabaseSeeder.php_ alterando o método ´run()´ para que fique de acordo com o código mostrado abaixo:

```php
public function run()
{
    \App\Models\User::factory(5)->create();
    \App\Models\Movie::factory(5)->create();
}
```

Salve os arquivos confirmando as alterações.

---

## Execução <a name="executing"></a>

> Migração

Certifique-se que o banco de dados está rodando, acesse o terminal novamente e digite o seguinte comando:

```php
php artisan migrate
```

O resultado esperado é a criação da tabela de usuários (users) no no MySQL e a tabela de filmes (movie) no SQLite.

![Database connection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7fbpzo57canbvq6uu9lk.jpg "Databases connections with tables")

---

> Seed

Volte ao terminal e execute o comando:

```php
php artisan db:seed
```

Agora temos 5 usuários e 5 filmes, cada um na sua respectiva tabela.

{% embed https://youtu.be/oR1c2iBGgBc %}

Optei por criar uma tabela pequena porque, como citado no início do artigo, o objetivo é mostrar os passos para configurar e utilizar mais de um banco de dados na mesma aplicação.

---

### Conclusão

Este cenário pouco comum tem diversas aplicabilidades.

Podemos, por exemplo, manter o registro de atividades da aplicação
em um banco de dados separado para efeitos de auditoria futura.

Outra possibilidade é criar um middleware que grave em uma tabela todas as requisições de entrada que foram realizadas em um período de tempo.

> Repositório

O código completo deste projeto pode ser visto {% embed https://github.com/MarcioPolicarpo/laravel9-multi-database %}.

---


Obrigado pela leitura e até a próxima.

Deixe nos comentários alguma situação onde seria interessante ter acesso simultâneo a mais de um banco de dados.