Explorando a persistência de dados com Room Database e MVVM
Tags: android, developer, mobile, programming
Published: 2023-07-05 16:49:47

Este artigo será para você, caro desenvolvedor Android que quer entender um pouco mais sobre a persistência de dados local no seu aplicativo utilizando nosso querido Room Database, um dos principais componentes de arquitetura dentro do Jetpack Components.

Você já sabe exatamente o que é o Room Database? Caso não saiba, fica tranquilo que eu vou te explicar com detalhes!
O Room Database é uma biblioteca do Android Jetpack que cria uma camada de abstração em cima do famoso SQLite, nos permitindo usar toda a capacidade dele. 

**Suas principais vantagens são:**
- Queries verificadas em tempo de compilação.
- Utilização de Annotations para redução de boilerplate.
- Fácil integração com outros Componentes de Arquitetura do Android.

Falando um pouco sobre as vantagens, como as queries são verificadas em tempo de compilação, não corremos o perigo de ter algum erro enquanto nosso aplicativo estiver executando. As Annotations, reduzem boilerplate pois não precisamos escrever todas as nossas queries, basta utilizarmos as Annotations juntas às nossas funções e através de um fenômeno chamado Reflection, quando o código for compilado, a biblioteca vai gerar o código das queries automaticamente e por isso é menos suscetível a erros.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l7ln3fv8wi8uzgffti62.png)

Dividimos o Room em três componentes principais:

**1. Entidade**
Cada entidade vai representar uma tabela dentro do nosso banco de dados, podemos ter por exemplo, uma entidade “user” no nosso aplicativo, então  será criada uma tabela chamada user no nosso banco. Usamos a annotation @Entity na classe User para comunicar o Room que ela será uma tabela no banco.

**2. DAO**
DAO é a sigla para Data Access Object, essa classe será responsável por definir os métodos que usaremos para acessar o banco, como por exemplo, um método para adicionar um novo usuário no banco ou um método para listar todos os usuários que estão cadastrados. Aqui podemos usar a annotation @Query para escrever SQL ou simplesmente usar a annotation @Insert para inserir algum dado.

**3. Database**
Nossa classe Database vai ser o ponto de acesso principal para conectar o aplicativo ao banco de dados, através dela conseguimos usar os métodos criados no nosso DAO.

Sei que pode ter ficado confuso, então vamos logo para a prática!

Para implementarmos nosso primeiro banco de dados usando Room, precisaremos de alguns passos.

**1. Adicionar as dependências**

Primeiramente, colocamos no nosso build.gradle dentro de plugins, o kotlin kapt.
```
plugins {
   id 'com.android.application'
   id 'org.jetbrains.kotlin.android'
   id 'kotlin-kapt'
}
```
		
Agora vamos adicionar as dependências no nosso build.gradle, vamos utilizar dependências para o LiveData, para o Room Database, para o ViewModel e para conseguirmos utilizar as nossas annotations.

```
def room_version = "2.4.1"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

def lifecycle_version = "2.5.1"
def arch_version = "2.1.0"

// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Annotation processor
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"	
```
**2. Criar nossa entidade**

Para criarmos nossa entidade, seguiremos alguns passos:

- Criar uma data class com a annotation @Entity e o parâmetro tableName para dar nome a tabela do banco de dados.

- Para a coluna id vamos utilizar a annotation @PrimaryKey com o parâmetro autoGenerate = true, isso vai nos garantir um id único para cada registro no banco de dados e o próprio Room vai criar sequencialmente(0, 1, 2, 3…). 

- Para o resto das colunas vamos utilizar a annotation @ColumnInfo e o parâmetro vai ser o nome que queremos dar a coluna.

```
@Entity(tableName = "car_table")
data class Car(
   @PrimaryKey(autoGenerate = true)
   val id: Int = 0,

   @ColumnInfo(name = "car_model")
   val carModel: String,

   @ColumnInfo(name = "car_color")
   val carColor: String,

   @ColumnInfo(name = "car_plate")
   val carPlate: String,
)
```

**3. Criar nosso DAO**

Agora vamos criar uma interface com a annotation @Dao, onde estarão os métodos para fazer operações no banco.
```
@Dao
interface CarDAO {
   @Insert
   fun insertCar(car: Car)

   @Query("SELECT * FROM car")
   fun listAllCars() : LiveData<List<Car>>
}
```

**4. Criar nosso ViewModel**

Vamos criar uma classe para o nosso ViewModel e colocar o Dao como construtor da classe. Agora vamos conseguir de fato realizar as operações no banco.
```
class MainViewModel(
   private val dao: CarDAO
) : ViewModel() {
   val carLiveData : LiveData<List<Car>> = dao.listAllCars()

   fun insertCarToDatabase(car: Car) {
       viewModelScope.launch(Dispatchers.IO) {
           dao.insertCar(car)
       }
   }
}
```


Com todas essas classes criadas, basta criarmos uma instância do nosso ViewModel na nossa Activity e nosso aplicativo está pronto para salvar e ler os dados dentro do Room Database. Também é possível criar operações para deletar e editar registros, fica como desafio para vocês!

Agora você já está preparado para criar alguns apps como uma lista de contatos ou uma lista de compras.

Por último, vou deixar o link da documentação de como criar uma instância do nosso ViewModel.

[Android View Model](https://developer.android.com/topic/libraries/architecture/viewmodel?hl=pt-br)

Espero que eu tenha te ajudado a entender como o Room Database funciona e como implementá-lo. Vejo vocês em breve!