Imprimir este capítuloImprimir este capítulo

Livro 3 - Projeto Agenda de Contatos - Parte 3

3. Biblioteca Room e persistência de dados

3.3. Classe ContactsDAO (DAO)

O que é DAO?

Em um objeto DAO (Data Acess Object) vão ser declaradas as consultas SQL bem como sua associação a métodos específicos. O compilador verifica os comandos SQL e gera as consultas por conveniência através de anotações como @Insert, por exemplo.

Um objeto DAO deve ser implementado como uma interface ou uma classe abstrata. Assim, a biblioteca Room cria automaticamente uma API sem você precisar escrever muito código. Como resultado temos um código mais limpo.

Por padrão, todas as consultas são executadas em uma thread separada. Dessa forma, o programador não precisa de preocupar em implementar essa tarefa tão comum para cada consulta criada, tornando o processo do desenvolvimento do aplicativo mais rápido e produtivo!

Implementação da classe ContactsDAO

Na Agenda de Contatos vamos usar o banco de dados SQLite para armazenar contatos com nome, telefone e e-mail. Nesse aplicativo, vamos usar três telas: uma para exibir a lista de contatos, uma para adicionar ou editar um contato já existente e uma para exibir os detalhes de um contato selecionado. Portanto, precisamos implementar o DAO para realizar as seguintes operações:

  • Pesquisar todos os contatos salvos no banco de dados
    • e também pesquisar todas as informações de um contato específico
  • Inserir um novo contato
  • Editar um contato já existente
  • Apagar um contato específico
    • e também apagar todos os contatos da agenda. Usaremos essa consulta na fase de testes do aplicativo.

O código completo da classe ContactsDAO fica como:

package ...

import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;

import java.util.List;

@Dao
public interface ContactsDAO {
@Query("SELECT * from contacts_table ORDER BY name ASC")
LiveData<List<Contact>> getAllContacts();

@Query("SELECT * from contacts_table WHERE id=:id")
LiveData<Contact> getContactById(int id);

@Insert
void insert(Contact contact);

@Update
void update(Contact contact);

@Delete
void delete(Contact contact);

@Query("DELETE FROM contacts_table")
void deleteAll();
}

  • @DAO
    • Anotação usada para identificar a classe como um DAO
  • @Query
    • Anotação usada para declarar uma consulta manualmente ao banco de dados. Declare entre os parênteses a consulta desejada. Logo abaixo da anotação deve ser implementado um método para executar a consulta.
    • Neste projeto duas consultas são declaradas, uma para buscar todos os contatos e outra para buscar apenas o contato com o id selecionado.
    • Observe que em ambos os casos o objeto de retorno é um dado do tipo LiveData<Tipo>. Esse é o retorno padrão dos métodos da biblioteca Room e é um dos componentes de arquitetura do Android Jetpack. Para mais informações consulte a documentação
  • @Insert, @Update, @Delete
    • Anotação para uma consulta do do tipo insert (inserção), update (atualização) e delete (remoção). Esse tipo de operação é extremamente comum logo não é necessário especificar nenhum comando SQL.
  • Método deleteAll
    • Não existe uma anotação para deletar todos os dados de uma tabela, logo devemos usar @Query para declarar manualmente o comando SQL para esse fim. De fato, para todos os casos em que não exista uma anotação conveniente, o comando SQL deve ser declarado explicitamente com a anotação @Query.

A classe LiveData

Quando os dados mudam você provavelmente deseja executar alguma ação, como exibir os dados atualizados na tela. Isso significa que você deve observador esse dados para perceber essas mudanças e ter uma reação. Dependendo de como os dados são armazenados, isso pode ser complicado. Observar mudanças nos dados através de múltiplos componentes dentro do aplicativo pode criar, explicitamente, dependências rígidas entre os componentes. Isso torna a tarefa de depurar e testar o código mais difícil, entre outras coisas.

LiveData, classe para observar dados, presente na biblioteca de componentes de ciclo de vida (lifecycle) dentro do Android Jetpack, representa uma solução para esse problema. A biblioteca Room usa esse tipo de dado para ser o valor de retorno das consultas ao banco e gera automaticamente todo o código necessário para atualizar a LiveData quando o banco de dados é atualizado.