Vistas de Base de Dados Com Espaço para Android

Room é uma camada de abstracção sobre SQLite que o Google empacotou como uma biblioteca AndroidX e também recomenda. Desde a versão 2.1, Room oferece a capacidade de adicionar Visualizações de Banco de Dados, também conhecidas como consultas armazenadas.

Algumas das boas razões para usar Visualizações de Banco de Dados seriam:

  • Facilitam escrever consultas complexas e usá-las em consultas de Objeto de Acesso a Dados (DAO).
  • Pode consultar apenas os campos que precisa, em vez de ter de percorrer todos os campos de uma tabela.

Neste tutorial, estará a construir uma aplicação de Customer Surveys que permite aos clientes de um restaurante deixarem feedback, e depois guarda esse feedback na base de dados Room managed. Durante o processo irá aprender o seguinte:

  • O que é uma vista de base de dados?
  • Como criar vistas de base de dados?
  • Como utilizá-las para simplificar a escrita de consultas SELECT
Nota: Este tutorial assume que tem experiência no desenvolvimento para Android no Kotlin e que já trabalhou com o Room antes. Se você não está familiarizado com Room, dê uma olhada no nosso tutorial Persistência de Dados com Room.

Este tutorial também usa Coroutines with Room. Para saber mais, leia o nosso tutorial Coroutines With Room Persistence Library.

Próximo Início

Baixar o projeto inicial clicando no botão Download Materials na parte superior ou inferior deste tutorial.

Extrair o arquivo ZIP e abrir o projeto inicial no Android Studio 4.0 ou posterior selecionando Abrir um projeto Android Studio existente na tela de boas-vindas.

A partir do momento em que a sincronização Gradle estiver completa, explore a estrutura do projeto. O projeto segue a arquitetura MVVM, então funcionalidades similares estão em um pacote. Familiarize-se com os pacotes presentes – você vai usá-los neste tutorial.

Build e execute. Você verá uma tela simples com uma mensagem de boas vindas, uma imagem e um botão START SURVEY.

>

Tela Start Survey do aplicativo SURVEY do cliente

>

Tapa o botão START SURVEY. Para efeitos deste tutorial, pode ignorar o facto de não ter comido uma refeição no restaurante:]

A tela seguinte é a tela do inquérito. Ela tem um campo de entrada de e-mail, botões de rádio para escolher a refeição que você está avaliando e três perguntas. Cada pergunta tem botões Bom, Médio e Ruim abaixo deles, para que o usuário possa avaliar sua satisfação.

Tela da pesquisa de opinião do cliente com perguntas e possíveis classificações

Verá também o botão SUBMIT SURVEY. Toque nele e você verá um brinde que diz que ainda não é hora de fazer a pesquisa. Não se preocupe, você vai corrigir isso ao longo deste tutorial.

Você agora foi bem-vindo ao The View Restaurant, onde você vai poder ver vistas incríveis da natureza, provar suas deliciosas refeições e avaliar sua satisfação. Enquanto estiver nele, você também aprenderá sobre Room Database Views.

Using Database Views

Considerar uma tabela que tem funcionalidade extra de consultas SELECT pré-embaladas para conveniência. A versão 2.1 e superior da sala chama-as como uma Vista de Banco de Dados e fornece uma anotação com o mesmo nome, ou seja, @DatabaseView.

Utilizando esta anotação você pode marcar uma classe para se comportar como uma Visualização de Banco de Dados. Isto permitirá que você anexe uma consulta à classe, como abaixo:

@DatabaseView("SELECT user.id, user.name " + "AS departmentName FROM user " + "WHERE user.departmentId = department.id")class User { var id: Long = 0 var name: String? = null}

Você pode então usar esta classe no seu DAO para consultar dados da mesma forma que você faria com uma classe marcada como uma Entidade, ou seja, Tabela em um banco de dados.

Um DAO ajuda você a acessar dados do banco de dados da sua aplicação. Ele normalmente contém os métodos CUD (Create, Update and Delete) e também pode conter outros métodos que podem ser necessários para acesso de leitura e escrita ao banco de dados.

A relação entre as Visualizações do Banco de Dados e o banco de dados é similar à relação entre as entidades e o banco de dados. Você vai dar uma olhada mais profunda nessas relações a seguir.

Comparando uma Vista de Banco de Dados e uma Entidade

As classes anotadas com @DatabaseView são similares a Entity classes. Eis como:

  • ambos podem usar SELECT FROM nas consultas DAO.
  • Database Views e Entitys podem ambos usar @ColumnInfo, o que permite personalizar a informação da coluna associada a um campo.
  • ambos podem usar @Embedded, o que permite que um campo tenha campos aninhados que as consultas podem referenciar directamente.

Embora haja muitas semelhanças entre os dois, também há diferenças entre DatabaseViews e Entitys:

  • Pode usar INSERT, UPDATE e DELETE com um Entity, mas não com um DatabaseView.
  • Você define todas as suas vistas em seus aplicativos usando views, mas você define entidades usando entities.

Agora você sabe o que é um DatabaseView e como ele se compara e contrasta com uma classe Entity, é hora de usá-lo e começar a enviar a pesquisa para o The View Restaurant.

Submeter a pesquisa

Seu primeiro passo é adicionar a lógica para enviar a pesquisa e salvá-la no banco de dados do Room depois de tocar no botão SUBMIT SURVEY.

Navigate to customersurveys/CustomerSurveyFragment.kt, onde você adicionará a lógica para coletar as respostas e salvá-las no Room. Faça isso substituindo o código em submitSurvey() por this:

// 1val email = editEmail.text.toString()// 2if (validateEmail(email)) { // 3 val meal = when (radioGroupMeals.checkedRadioButtonId) { R.id.radioBreakfast -> "Breakfast" R.id.radioLunch -> "Lunch" R.id.radioDinner -> "Dinner" else -> "No Meal" } // 4 val customerSurvey = SurveyListItem .CustomerSurvey(0, email, meal, questionOneAnswer, questionTwoAnswer, questionThreeAnswer) customerSurveyViewModel.insertCustomerSurvey(customerSurvey) // 5 findNavController() .navigate(R.id.action_surveyFragment_to_surveyCompletedFragment)}

Aqui está o que você está fazendo com este código:

  1. Você recebe o e-mail de editEmail e o atribui a uma variável: email.
  2. Esta verificação de condição chama validateEmail(email), que verifica se o email é null ou não. Ele retorna false se for null. Também verifica se o e-mail digitado é válido e retorna false se não é.
  3. O código dentro da instrução if executa quando validateEmail(email) retorna true. meal contém o tipo de refeição que o usuário selecionou dos grupos de rádio.
  4. Embora tenha o valor de meal, você cria SurveyListItem.CustomerSurvey, que tem toda a informação sobre a pesquisa. Ele puxa os valores para questionOneAnswer, questionTwoAnswer e questionThreeAnswer de toggleButtonListeners(), que tem ouvintes para esse fim.
  5. Aqui, você salva customerSurvey chamando insertCustomerSurvey(customerSurvey) em CustomerSurveyViewModel, que lida com a lógica para salvar em Sala.
  6. Navega-se para SurveyCompletedFragment.

Depois de adicionar isto, vai notar que customerSurveyViewModel e findNavController() têm um sublinhado vermelho. Para corrigir isso, primeiro adicione a CustomerSurveyViewModel inicialização no topo da classe, logo abaixo da questionThreeAnswer inicialização.

private val customerSurveyViewModel: CustomerSurveyViewModel by viewModels()

Certifique-se de adicionar as respectivas instruções de importação quando o IDE lhe pedir.

Build e execute. Inicie o questionário, digite a entrada de e-mail necessária e selecione as respostas às perguntas.

>

Tela de questionário com respostas

>

Great, você completou o questionário.

Veja todos os questionários usando a captura de tela de Vistas de Banco de Dados

>

Tapa o botão VIEW SURVEYS… oops, ele ainda não faz nada. Não se preocupe, você vai consertar isso em breve.

Na próxima seção, você aprenderá como criar sua primeira DatabaseView.

Criando uma vista de banco de dados

Para criar uma vista, você adicionará uma @DatabaseView anotação a uma classe ou classe de dados. Comece navegando para clientsurveys/SurveyListItem.kt. Esta é uma classe selada com um par de classes de dados para você usar neste tutorial.

No final de SurveyListItem, logo abaixo de QuestionOneSadView, adicione o seguinte:

data class HappyBreakFastView( override val email: String) : SurveyListItem()

Esta classe de dados substitui a variável de e-mail de SurveyListItem e herda da classe – significando que é um subtipo de SurveyListItem.

Após criar esta classe de dados, adicione @DatabaseView com uma consulta SELECT para ir buscar todos os ids de email da tabela CustomerSurvey onde a refeição está definida como “Breakfast”, logo acima da classe de dados HappyBreakFastView. A sua anotação deve ser parecida com esta:

@DatabaseView("SELECT CustomerSurvey.email FROM CustomerSurvey WHERE CustomerSurvey.meal = 'Breakfast'")

Umas coisas a notar sobre a consulta dentro da anotação:

  • A consulta funciona como qualquer outra consulta que tenha escrito no Room.
  • Precisa de solicitar todos os campos que tem na sua classe de dados enquanto escreve a consulta. Neste caso, você só precisa do e-mail. Você usa SELECT CustomerSurvey.email From... para obter o email de CustomerSurvey.
Nota: Para este tutorial, mantenha as vistas e a entidade dentro do SurveyListItem para evitar repetições e para tornar o código mais fácil de ler. Nem sempre é necessário subclassificar suas views em uma classe selada; elas também podem estar em seu próprio arquivo separado ou classe.

Congratulações, você criou sua primeira view! A seguir, você vai ver como pode usar a vista nas suas consultas DAO.

Utilizar as vistas da base de dados da sala nas consultas DAO

Primeiro, você incluirá HappyBreakFastView em views nos aplicativos @Database.

Navigar para base de dados/AppDatabase.kt e, dentro de views, adicione SurveyListItem.HappyBreakFastView::class. Sua atualização @Database anotação deve ser como abaixo:

@Database(entities = , version = 2, exportSchema = false, views = )

Note que o version = 2. Você precisa atualizar a versão do banco de dados toda vez que você adicionar um view no AppDatabase – caso contrário, o seu aplicativo irá travar. Neste caso, você atualizou a versão para 2. Sync gradle para aplicar todas estas alterações.

Next, navegue para clientes/CustomerSurveysDao.kt e, logo abaixo de getQuestionOneSadView(), adicione o seguinte código:

>

@Query("SELECT * FROM HappyBreakFastView")fun getHappyBreakFastCustomers():LiveData<List<SurveyListItem.HappyBreakFastView>>

Este método obtém todos os clientes que ficaram satisfeitos com qualquer aspecto da pesquisa do restaurante. Para explicá-lo com mais detalhes:

  • Primeiro, você usa HappyBreakFastView como faria em uma consulta normal.
  • Você chama este método em CustomerSurveyRepo para obter uma lista de todos os clientes que responderam a qualquer uma das perguntas com o Bem. Note que o tipo de retorno do método é uma lista LiveData do tipo SurveyListItem.HappyBreakFastView, que é um suporte de variável observável.

Agora, você criou um view e o método para consultar a lista de clientes que responderam com uma resposta positiva em CustomerSurveysDao. Na próxima seção, você aprenderá como chamar este método da classe de repositório.

Recebendo Dados Usando uma Visão de Banco de Dados

Navigate to customersurveys/CustomerSurveyRepo.kt e adicione o seguinte método logo abaixo getQuestionOneSadView():

fun getHappyBreakFastCustomers() : LiveData<List<SurveyListItem.HappyBreakFastView>> { return customerSurveysDao.getHappyBreakFastCustomers()}

Este método chama getHappyBreakFastCustomers() de CustomerSurveysDao para obter os dados do Room. Seu tipo de retorno é um LiveData, o que permite ao chamador deste método observar quaisquer alterações nos dados.

Próximo, você adicionará uma chamada para getHappyBreakFastCustomers() em CustomerSurveyViewModel. Ele é responsável por exibir os dados para a visualização – que, neste caso, não é DatabaseView mas sim AllSurveysFragment.

Navigate to customersurveys/CustomerSurveyViewModel.kt e adicione o seguinte código:

val happyBreakfastCustomers : LiveData<List<SurveyListItem.HappyBreakFastView>> by lazy { customerSurveyRepo.getHappyBreakFastCustomers()}

Esta variável obtém seu valor chamando getHappyBreakFastCustomers() de CustomerSurveyRepo. Há um by lazy{} para que você não carregue os dados imediatamente, mas sim quando a variável for acessada pela primeira vez.

Próximo, você atualizará a IU para que ela possa exibir os dados.

Exibindo os dados para a IU

Navigate to allsurveys/AllSurveysFragment.kt e adicionar o seguinte código no final da classe:

private fun getHappyBreakfastCustomers() { customerSurveyViewModel.happyBreakfastCustomers.observe(viewLifecycleOwner, Observer { customerSurveyList -> if (customerSurveyList.isEmpty()) { layoutEmptyView.visibility = View.VISIBLE rvReviews.visibility = View.GONE } else { layoutEmptyView.visibility = View.GONE rvReviews.visibility = View.VISIBLE initView(customerSurveyList) } })}private fun initView(customerSurveySurveyList: List<SurveyListItem.HappyBreakFastView>) { val customerSurveysAdapter = CustomerSurveysAdapter(customerSurveySurveyList) rvReviews.adapter = customerSurveysAdapter}

Para explicar o que o código faz:

  • Primeiro, ele chama happyBreakfastCustomers e observa o seu valor.
  • No interior da lambda de observação, há uma verificação para ver se o clienteSurveyList é null ou não. Se a lista for null, você define a mensagem TextView‘s No surveys found! para visível e esconder RecyclerView. Se não for null, você define a visibilidade de TextView para GONE e mostra RecyclerView. Você também chama initView(customerSurveyList) com o valor customerSurveyList de CustomerSurveyViewModel.
  • initView(customerSurveySurveyList: List) inicializa CustomerSurveysAdapter com customerSurveyList e define o adaptador para RecyclerView para CustomerSurveysAdapter, que agora exibe a lista de pesquisas para a UI.

O IDE irá solicitar que você adicione a importação de SurveyListItem. Se não, adicione esta importação:

import com.raywenderlich.android.customersurveys.customersurveys.SurveyListItem

Agora que você exibiu os dados para a IU, você tem apenas mais alguns passos antes que tudo funcione perfeitamente.

Próximo, você adicionará o código que lida com a busca de dados do Room, dependendo da opção selecionada no menu suspenso na interface do usuário, ou seja, o widget Spinner.

Visualizando Dados para as Diferentes Visualizações

Adicionar o seguinte código logo abaixo de onCreate em AllSurveysFragment.kt::

private fun spinnerListener() { filterSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?) {} override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { when (position) { 0 -> resetState() 1 -> getAllCustomerSurveys() 2 -> getHappyBreakfastCustomers() 3 -> getSadDinnerCustomers() 4 -> getAverageLunchCustomers() 5 -> getQuestionOneSadCustomers() } } }}

O código acima define onItemSelectedListener a filterSpinner e sobrepõe-se a dois métodos: onNothingSelected e onItemSelected. Você não quer fazer nada quando nada é selecionado, então onNothingSelected é deixado vazio. Você não quer reagir quando um Item é selecionado, então você precisa implementar onItemSelected.

onItemSelected tem uma expressão when que chama métodos diferentes, dependendo da opção selecionada em filterSpinner. Esses métodos são similares a getHappyBreakfastCustomers(), mas eles buscam dados usando uma expressão diferente em DatabaseView.

>

Certifique-se de adicionar as importações quando o IDE solicitar.

Finalmente, adicione uma chamada para spinnerListener() dentro de onViewCreated, logo após setupSpinner(), como mostrado abaixo:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupSpinner() // Added spinnerListener()}

Agora que você tenha tudo pronto para buscar as pesquisas, seu próximo passo é adicionar o código para navegar até AllSurveysFragment.

Navigar para todas as pesquisas

Esta é a última etapa que você precisa para ver as vistas em ação.

Navigar para completardsurvey/SurveyCompletedFragment.kt e descomentar o código dentro de btnViewSurveys. Seu resultado final será assim:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) btnViewSurveys.setOnClickListener { findNavController() .navigate(R.id.action_surveyCompletedFragment_to_allSurveysFragment) }}

Aqui, você está simplesmente configurando o ouvinte de cliques para o botão VIEW SURVEYS e navegando para AllSurveysFragment.

Após descomentar o código, a IDE irá solicitar que você importe findNavController(). Basta importar o necessário.

Build, executar e iniciar uma pesquisa, depois responder as perguntas e enviá-las. Finalmente, veja All Surveys, onde você poderá buscar todos os dados dependendo da opção selecionada no spinner.

Opçõespinner no app
Lista de clientes muito felizes usando uma Vista de Banco de Dados
Jantar de clientes não encontrados usando uma Vista de Banco de Dados

Congratulações! Você terminou a sua experiência no The View Restaurant. Esperamos que você tenha tido uma ótima refeição, visto vistas incríveis e tido a chance de aprender o que são DatabaseViews.

Aonde Ir A partir daqui?

Baixar o projeto final usando o botão Download Materials no topo ou no fundo do tutorial.

>

Para mais informações sobre os recursos do Room, confira a documentação oficial do Android.

>

Esperamos que você tenha gostado deste tutorial Room Database Views. Se você tiver alguma dúvida, comentário ou modificações incríveis neste aplicativo do projeto, por favor, junte-se à discussão do fórum abaixo.

raywenderlich.com Weekly

A newsletter raywenderlich.com é a maneira mais fácil de se manter atualizado sobre tudo o que você precisa saber como um desenvolvedor móvel.

Receba um resumo semanal dos nossos tutoriais e cursos, e receba um curso gratuito por e-mail em profundidade como bónus!

Avaliação média

4.8/5

Adicionar uma classificação para este conteúdo

Entrar para adicionar uma classificação

10 classificações

Leave a Reply