Pesquise algo no blog

sexta-feira, 1 de maio de 2015

Curso Android Aula 10 - CRUD SQLite Insert


Introdução


Esta aula é continuação das aulas 08 e da aula 09, onde criamos um formulário de login com validações dos campos. Agora iremos adicionar ao aplicativo Android a persistência dos dados no SQLite. Gravar os dados no banco de dados é uma das atividades mais importantes no meu ponto de vista. 

O Android disponibilizar suporte completo ao SQLite, que é um banco de dados customizado para aplicativos móveis, free, leve e de certa forma bastante robusto.

Esta aula além de introduzir o uso do SQLite, também contém a aplicação de vários recursos do android e rotinas comuns em aplicações Android como por exemplo, trabalhar com multiplo botões, fazer uso de interfaces do SDK Android para reduzir codificação Java.

Também estaremos implementando o conceito de programação em camadas.

Objetivo


O objetivo desta aula será iniciar a implementação de um CRUD utilizando a plataforma Android e o SQLite. Nesta aula, iremos refatorar nosso projeto para que possamos trabalhar com o SQLite.

Vamos separar em camadas os novos pacotes da aplicação. Isso tem como vantagem principal, separas as responsabilidades de cada pacotes e organizar o projeto. Iremos criar um pacote para a DAO, um para DATAMODEL e outro para a DATASOURCE. 

Video demonstrativo da aplicação rodando no emulador





Assista o video demonstrando o resultado final desta aula. No video eu mostro como visualizar os dados gravados no banco de dados e como copiar o banco de dados do emulador para o desktop do seu computador.

Fundamentação teórica


Entenda de forma bem simples e fundamental, os conceitos que iremos utilizar nesta e nas próximas aulas para implementar a persistência de dados ao nosso aplicativo Android.

O que é um CRUD?


Um CRUD nada mais é do que uma sigla para representar as operações básicas manter dados em um banco de dados. Seu significado é: Create, Retrieve, Update e Delete, o que representão respectivamente um Insert, um Select, um Update e um Delete dos scripts SQL utilizados para manipular os dados de um banco de dados relacional.

O que é DAO?


Data Access Object (DAO) é um padrão de projetos para parsistência de dados que permite separar regras de negócio das regras de acesso ao banco de dados. Em uma aplicação que utilize a arquitetura MVC, todas as funcionalidades de persistência de dados, tais como obter as conexões, mapear objetos Java para tipos de dados SQL ou executar comandos SQL, devem de responsabilidade da camada DAO do projeto.

As demais camadas não podem acessar diretamente o banco de dados, e em um cenário ideal, bem sabem como executar tarefas de persistência de dados. O que elas sabem é solicitar um serviço para as demais camadas.

O que é Data Model?


Data Model organiza e padroniza a forma como os elementos de dados se relacionam entre si. Desde elementos de documentais, como pessoas do mundo real, lugares, coisas e os relacionamentos entre elas. É um padrão necessário para garantir uma comunicação exata entre a programação orientada a objetos e o mundo real.

O que é Data Source?


Data Source é o nome dado à configuração de conexão para um banco de dados de um servidor. O nome é normalmente utilizado quando cria-se uma consulta para o banco de dados.


Protótipo da Tela de Login (Refatorada)





Nesta aula iremos adicionar mais um botão na tela principal da aplicação. Este botão quando acionado, irá salvar os dados no banco de dados respeitando as mesmas regras de validação definidas para o botão acessar. Somente com todos os dados informados nos campos Login e Senha será permitido acessar o botão SALVAR LOGIN e acessar a tela Dashboard.

Programando o botão Salvar - Primeira parte Layout




Vamos implementar as alterações necessários no layout para que possamos adicionar o botão salvar e assim programar o mesmo na activity da tela de login.

Adicione o Widget Button ao layout activity_main.xml conforme definições abaixo:





Note que o ID definido para o botão é btnSalvar. E será utilizado para implementar a programação Java do mesmo.

Observer a propriedade android:enabled="false". O botão salvar estará indisponível para o usuário, até que o mesmo informe os dados corretamente.

Compare o seu layout com o protótipo da tela apresentado na figura acima. Não é necessário que fique perfeitamente como o protótipo da aula. O importante é manter os mesmos IDs, textos, nomes de variáveis, etc.

Programando o botão Salvar - Segunda parte codificação Java


A tela de Login agora tem dois botões, e teremos que implementar duas regras de negócio além de capturar corretamente qual dos dois botões o usuáio clicou.

Isso será feito implementando a interface OnClickListener, o que irá nos permitir trabalhar com multiplos botões.

Primeiro passo para implementar a interface OnClickListener. 


Adicione o código Java apresentado na linha 16 abaixo.



Aproveite para criar o objeto btnSalvar conforme linha 24.

Segundo passo, implementar o método onClick().


Adicione o método onClick() conforme demonstrado no código abaixo. Este método irá capturar o click dos botões, e iremos programaticamente testar qual dos botões foi clicado e aplicar a regra de negócio conforme cada caso. Este método deve ser adicionado logo após o método onCreate().




Terceiro passo, refatorar o método setOnClickListener() para os dois botões.




Basicamente estamos setando para os dois botões btnAcessar e btnSalvar o método setOnClickListener(). Com esta alteração, a interface OnClickListener() ficara "ouvindo" as ações de click do usuário, e chamará o método onClick() definido no segundo passo.

Note que na linha 43, estamos vinculando o botão btnSalvar ao Widget Button do Layout.

Quarto passo, descobrir qual botão foi clicado pelo usuário.


Neste caso, usaremos a estrutura condicional switch/case para capturar qual botão foi clicado, usando o ID definido para o mesmo na criação do Layout via propriedade android:id.

Adicione a código destacado na imagem abaixo ao seu projeto.




Refatorando as regras de validação para o botão btnAcessar.


A validação consiste em testar se o usuário digitou para os campos Login e Senha as informações corretas, no caso o Login é aula@foo.maddo e a Senha android.




Na linha 88, estamos ativando o botão btnSalvar. Isso acontecerá somente se os campos digitados forem válidos.

Criação dos Pacotes para o Projeto


Talvés você ainda não percebeu, mas a estrutura dos projetos Android é semelhante ao padrão de projeto MVC, que significa Model, View e Controle.

A Model contém as classes em Java, a View contém as telas ou a interface de comunicação entre a aplicação e o usuário e a Controle contém as regras de negócios da aplicação.

Nós iremos criar um pacote para a Model e neste pacote criaremos uma classe chamada Login.java. A vantagem principal será trabalha com Objetos em nosso projeto, isso vai facilitar a manutenção, além de forçar a prática da Progrmação Orientada a Objetos em Java com Android.


Crie um pacote chamado model e adiciona a classe Login.java confome demonstrado nas figuras abaixo:


Criação do Pacote Model






Selecione o pacote foo.maddo.cursoandroidaula10 e click com o botão direito -> New -> Package.


Resultado esperado







Criação da Classe Login.java


Selecione o pacote MODEL, clique com o botão direito -> New -> Java Class e crie a classe Login.Java


Nomeando a Classe





Classe Login.java


A classe Login, conterá apenas três atributos privados, sendo o ID que será gerado toda vez que um registro for incluído ao banco de dados, um atributito String login e por último um atributo String senha. Como esta classe pertence a camada Model, ela não receberá nenhum método adicional a não ser os respectivos gets e sets.






Criação do Pacote DAO - Data Access Object - LoginDAO.Java


Esta camada receberá a classe que terá a função tratar os objetos da camada superior, no caso a VIEW representada pelas Activities Android e enviar para a DataSource para serem gravadas no Banco de Dados. A DAO também será responsável em devolver dados do banco de dados para a VIEW que solicitar.

Nesta aula iremos implementar na classe LoginDAO apenas o método adicionar() do nosso CRUD. Nas próximas aulas estaremos implementando todos os demais métodos.

Crie o pacote DAO e dentro dele a classe LoginDAO.java conforme figura abaixo:





Classe LoginDAO.Java


Esta é a estrutura da classe LoginDAO que será implementada nesta aula. Note que temos o construtor padrão da classe, e um método boleano que recebe o objeto Login na sua assinatura.

Até aqui, esta classe não contém nada de extraordinário, mas iremos "decorar" esta classe com os pré-requisitos Android para permitir a integração da DAO com o SDK Android, especificamente para efetuar a persistência dos dados no SQLite.

É muito importante para o sucesso do seu aprendizado que você perceba a evulução desta aula, se você notar, estamos construindo gradativamente a aplicação, e implementando conforme necessário as alterações na codificação Java comum para outras plataformas de desenvolvimento.




Construtor LoginDAO()


Nosso construtor será responsável em entregar um objeto de banco de dados, vindo da DataSource de forma a permitir que todos os métodos do CRUD tenham disponíveis o acesso aos métodos do SQLite para incluir, alterar, deletar ou listar os dados solicitados pela aplicação.


Método adicionar(Login obj)

Este será o primeiro método do CRUD que será implementado. Estaremos enviando um objeto Login para ser adicionado ao banco de dados. O método adicionar, é do tipo booleano. Caso o objeto seja adicionado com sucesso no Banco de Dados, retorna true, caso contrário retorna falso para a VIEW que notificará o usuário.


Criação do Pacote DataModel


Vamos adicionar mais um pacote ao nosso projeto, neste caso será o pacote DataModel. O papel deste pacote será criar a classe DataModel responsável em manter o que podemos chamar de modelo de dados, ou dicionário de dados do banco de dados, além dos scripts para criar as tabelas no SQLite.




Classe DataModel


Na classe DataModel iremos manter as definições das tabelas que serão usadas pelo Banco de Dados, os nomes dos seus atributos, os seus respectivos tipos de dados e por fim os scripts para criação das tabelas.

Todas as definições serão consumidas pela classe DataSouce, que será a próxima classe a ser implementada dentro do pacote DataSouce.




Significado dos Atributos


  • DB_NAME - Nome do banco de dados
  • TABELA_LOGIN - Nome da tabela "login"
  • ID - Nome do atributo ID
  • LOGIN - Nome do atributo LOGIN
  • SENHA - Nome do atributo SENHA
  • TIPO_TEXTO - Tipo de dados do SQLite para textos, strings, caracteres
  • TIPO_INTEIRO - Tipo de dados do SQLite para valores inteiros
  • TIPO_INTEIRO_PK - Tipo Inteiro e definição para chave primária da tabela 

Métodos 


  • criatTabelaLogin() - Retorna uma string contendo o script SQL para criar a tabela no banco de dados.


Criação do Pacote DataSouce


Este será o último pacote que iremos criar nesta aula. Nele iremos implementar a classe SQLiteOpenHelper do Android, classe responsável pela criação do Banco de Dados.

Crie um novo pacote chamado DataSource -> New -> Packege -> datasource. Em seguida, crie uma classe dentro deste pacote chamada DataSouce.java -> New -> Java Class -> DataSource.java.




Depois de um pouco de trabalho para estruturar nosso projeto nesta aula, finalmente chegamos ao foco da aula, que é implementar um Insert de um objeto no banco de dados SQLite. Todo este esforço vai valer muito a pena, pois ganharemos tempos nas próximas aulas.

Outro detalhes muito importante, é que sem você perceber, criamos uma pequena arquitetura que pode ser aproveitada em outros projetos Android.

Vamos programas nossa classe de persistência de dados, partindo do zero.

Se você criou a classe DataSouce conforme solicitado, sua classe terá a aparencia conforme figura abaixo:



O próximo passo é extender a classe SQLiteOpenHelper.



Note que o compilador reporta um erro, isso se deve pelo fato de sermos obrigados a implementar os métodos da classe SQLiteOpenHelper.

Clique na palavras reservada public e em seguida clique na Lâmpada que o Android Studio irá disponibilizar com algumas sugestões para resolver este erro.



Após surgir as sugestões, clique em Implement methods.



Serão implementados dois métodos, o onCreate() e o onUpgrade().


  • Método onCreate() - Este método será executado apenas uma única vez e caso não existe, criará o banco de dados, conforme as definições definidas na DataModel.
  • Método onUpgrade() - Este método será executado toda vez que a versão do banco de dados for alterada. Em outras palavras, caso ocorra alguma modificação na estrutura do banco de dados, este método será executado e aplicará as alterações necessárias.



Ainda temos que criar o Construtor para a classe DataSource. 









Toda vez que um objeto DataSouce for criado, o construtor espera as seguintes informações:

  • context - Usado para abrir ou criar o banco de dados
  • name - É o nome do banco de dados no sistema de arquivos, caso seja null será criado um banco de dados apenas na memória.
  • factory - Usado para criar um cursor de objetos. Se este valor for null será criado um objeto default.
  • version - Este é o númedo da versão do banco de dados, iniciado por 1. Caso este número seja alterado para 2, significa que a estrutura do banco de dados foi alterada e o método onUpgrade() será executado.

Até aqui, a única informação que temos para o construtor é o nome do banco de dados que foi definido na DataModel. Mas até agora, não é possível acessar esta informação. Devemos adicionar os métodos de acesso gets para todos os atributos da DataModel.

Crie os gets apenas para o atributos selecionados na imagem abaixo:




A classe DataModel deverá ficar conforme demonstrado abaixo:




Podemos utilizar o método getDB_NAME() para informar ao construtor da DataSouce() qual será o nome do banco de dados para a nossa aplicação. Aqui começa a demonstração da vantagem de termos criado a DataModel.









Nos resta informar o context, factory e version. Vamos criar variáveis locais para factory e version. O context será fornecido pela camada de VIEW da aplicação, ou seja, pela classe Activity que desejar persistir algum objeto no banco de dados.




Observe que estamos passando para o construtor da classe extendida SQLiteOpenHelper, o contexto da aplicação, o nome da tabela, que veio da classe DataModel.getDB_NAME(), o valor null para a cursor, e o valor 1 para a versão do banco de dados.

Classe SQLiteDataBase - Criando o banco de dados


Estamos com quase tudo pronto para finalizar criação no banco de dados. Agora necessitamos de um objeto da classe SQLiteDataBase. Será este objeto que nos fornecerá os métodos para ler e escrever no banco de dados, executar insert, upgrade, delete, etc.

Neste momento do curso, não irei aprofundar os conceitos sobre esta classe, o que é assunto de outra aula específica sobre as classes SQLiteOpenHelper e SQLiteDataBase.

Adicione as linhas em destaque abaixo ao seu código Java da classe DataSource.





  • Linha 17 - SQLiteDatabase - Cria um objeto para manipular o banco de dados contendo vários métodos comuns para rotinas de persistência de dados.
  • Linha 23 - Abre o banco de dados para leitura.
  • Linha 30 - Cria caso não exista a tabela Login no banco de dados, a partir das definições da tabela criadas na DataModel.
  • Linha 39 -  Será executada somente se a versão do banco de dados for alterada.

Método para persistência dos dados no banco de dados - persist().


Vamos criar agora um método que não está disponível nativamente no SQLite. O método que iremos criar será chamado de persist(), e sua função será, executar um insert ou um upgrade no banco de dados. O insert é tema desta aula, o upgrade será o tema da próxima aula, porém, já deixaremos o método pronto.



A lógica deste método é baseada no status do atributo ID. Se o mesmo for zero ou nulo, significa que um registro novo deve ser adicionado ao banco de dados, caso contrário, será realizado um upgrade em um registro já existente.

Note que estamos passando o nome da tabela como parâmetro na assinatura deste método, isso torna-o muito reutilizável. Como poderemos ver nesta e nas próximas aulas.

A linha 65, executa o método insert do SQLiteDatabase efetuando a inclusão dos dados no banco de dados.

Observe que temos uma novidade neste método, que é o uso da Classe ContentValues. Esta classe recebe uma lista contendo dois valores,  o primeiro é o nome do campo na tabela, e o segundo é o valor que desejamos gravar para este campo no banco de dados.

Vamos retornar ao método adicionar da classe LoginDAO para preparar os dados para serem incluídos via método persist().


Refatorando a classe LoginDAO()





A classe LoginDAO até o momento contém apenas o método adicionar(). Para que possamos enviar o objeto Login para a DataSouce, teremos que modificar o código Java desta classe.


  • Linha 16 - Estamos criando um objeto DataSource.
  • Linha 17 - Estamos criando um objeto ContentValues, requerido pelo método persist() da DataSource.
  • Linha 19 - Modificamos a assinatura do construtor da classe para receber o contexto da aplicação.
  • Linhas 29 à 32 - Estamos criando uma estância da classe ContentValues e populando o objeto com os dados a serem enviado ao banco de dados.
  • Linha 35 - Estamos executando o método persist() passando como parâmetros os valores a serem salvos e o nome da tabela de destino dos dados no banco de dados.
  • Linha 36 - Setamos o retorno como true, o que significa que os dados foram salvos com sucesso. 

Refatorando as regras de validação para o botão btnSalvar.


O botão btnAcessar é configurado no layout como desabilitado, e somente quando o usuário informar os dados corretamente, o seu status muda de desabilitado para habilitado.

Quando o botão estiver disponível para o usuário, iremos enviar os dados para a camada LoginDAO, que providenciará a preparação do objeto Login para ser gravado no banco de dados.

Se os dados forem salvos corretamente no banco de dados, a troca de tela será efetuada e a tela Dashboard será carregada.





Esta é praticamente a última parte desta aula, onde estamos implementando a regra de negócio para gravar os dados no banco de dados.

Aqui nós criamos um objeto Login, populamos o mesmo com os dados digitados pelo usuário e enviamos para a classe LoginDAO, através do método adicionar().

Como é necessário informar o contexto da aplicação para a DataSouce(), estamos fazendo isso na linha 106. O método getApplicationContext() informa o contexto atual da Activity.

O método adicionar() da classe LoginDAO, irá devolver verdadeiro ou falso, dependerá se ocorreu ou não sucesso ao gravar os dados no banco de dados.

Por último, se tudo estiver correto, trocamos de tela carregando a Dashboard.

Fontes do projeto no GitHub


Os fontes deste projeto estão disponíveis no repositório Git do curso. Para acessar, basta clicar no link abaixo:

https://github.com/profmaddo/CursoAndroidAula10

Conclusão


Persistir dados em um banco de dados é uma das tarefas mais comuns em qualquer sistema, seja ele web, desktop ou mobile. Nesta aula, além de apresentar como criar uma classe para gravar os dados no banco de dados SQLite para Android, também tivemos a oportunidade de aprofundar um pouco mais conceitos importantes sobre separação de regras de negócios em camadas, DataModel, DataSource, DAO e MVC.

Finalizamos a aula com o primeiro método do CRUD implementado. Na próxima aula irei demonstrar como visualizar os dados gravados no banco de dados conforme figura abaixo.






sexta-feira, 1 de maio de 2015

Curso Android Aula 10 - CRUD SQLite Insert


Introdução


Esta aula é continuação das aulas 08 e da aula 09, onde criamos um formulário de login com validações dos campos. Agora iremos adicionar ao aplicativo Android a persistência dos dados no SQLite. Gravar os dados no banco de dados é uma das atividades mais importantes no meu ponto de vista. 

O Android disponibilizar suporte completo ao SQLite, que é um banco de dados customizado para aplicativos móveis, free, leve e de certa forma bastante robusto.

Esta aula além de introduzir o uso do SQLite, também contém a aplicação de vários recursos do android e rotinas comuns em aplicações Android como por exemplo, trabalhar com multiplo botões, fazer uso de interfaces do SDK Android para reduzir codificação Java.

Também estaremos implementando o conceito de programação em camadas.

Objetivo


O objetivo desta aula será iniciar a implementação de um CRUD utilizando a plataforma Android e o SQLite. Nesta aula, iremos refatorar nosso projeto para que possamos trabalhar com o SQLite.

Vamos separar em camadas os novos pacotes da aplicação. Isso tem como vantagem principal, separas as responsabilidades de cada pacotes e organizar o projeto. Iremos criar um pacote para a DAO, um para DATAMODEL e outro para a DATASOURCE. 

Video demonstrativo da aplicação rodando no emulador





Assista o video demonstrando o resultado final desta aula. No video eu mostro como visualizar os dados gravados no banco de dados e como copiar o banco de dados do emulador para o desktop do seu computador.

Fundamentação teórica


Entenda de forma bem simples e fundamental, os conceitos que iremos utilizar nesta e nas próximas aulas para implementar a persistência de dados ao nosso aplicativo Android.

O que é um CRUD?


Um CRUD nada mais é do que uma sigla para representar as operações básicas manter dados em um banco de dados. Seu significado é: Create, Retrieve, Update e Delete, o que representão respectivamente um Insert, um Select, um Update e um Delete dos scripts SQL utilizados para manipular os dados de um banco de dados relacional.

O que é DAO?


Data Access Object (DAO) é um padrão de projetos para parsistência de dados que permite separar regras de negócio das regras de acesso ao banco de dados. Em uma aplicação que utilize a arquitetura MVC, todas as funcionalidades de persistência de dados, tais como obter as conexões, mapear objetos Java para tipos de dados SQL ou executar comandos SQL, devem de responsabilidade da camada DAO do projeto.

As demais camadas não podem acessar diretamente o banco de dados, e em um cenário ideal, bem sabem como executar tarefas de persistência de dados. O que elas sabem é solicitar um serviço para as demais camadas.

O que é Data Model?


Data Model organiza e padroniza a forma como os elementos de dados se relacionam entre si. Desde elementos de documentais, como pessoas do mundo real, lugares, coisas e os relacionamentos entre elas. É um padrão necessário para garantir uma comunicação exata entre a programação orientada a objetos e o mundo real.

O que é Data Source?


Data Source é o nome dado à configuração de conexão para um banco de dados de um servidor. O nome é normalmente utilizado quando cria-se uma consulta para o banco de dados.


Protótipo da Tela de Login (Refatorada)





Nesta aula iremos adicionar mais um botão na tela principal da aplicação. Este botão quando acionado, irá salvar os dados no banco de dados respeitando as mesmas regras de validação definidas para o botão acessar. Somente com todos os dados informados nos campos Login e Senha será permitido acessar o botão SALVAR LOGIN e acessar a tela Dashboard.

Programando o botão Salvar - Primeira parte Layout




Vamos implementar as alterações necessários no layout para que possamos adicionar o botão salvar e assim programar o mesmo na activity da tela de login.

Adicione o Widget Button ao layout activity_main.xml conforme definições abaixo:





Note que o ID definido para o botão é btnSalvar. E será utilizado para implementar a programação Java do mesmo.

Observer a propriedade android:enabled="false". O botão salvar estará indisponível para o usuário, até que o mesmo informe os dados corretamente.

Compare o seu layout com o protótipo da tela apresentado na figura acima. Não é necessário que fique perfeitamente como o protótipo da aula. O importante é manter os mesmos IDs, textos, nomes de variáveis, etc.

Programando o botão Salvar - Segunda parte codificação Java


A tela de Login agora tem dois botões, e teremos que implementar duas regras de negócio além de capturar corretamente qual dos dois botões o usuáio clicou.

Isso será feito implementando a interface OnClickListener, o que irá nos permitir trabalhar com multiplos botões.

Primeiro passo para implementar a interface OnClickListener. 


Adicione o código Java apresentado na linha 16 abaixo.



Aproveite para criar o objeto btnSalvar conforme linha 24.

Segundo passo, implementar o método onClick().


Adicione o método onClick() conforme demonstrado no código abaixo. Este método irá capturar o click dos botões, e iremos programaticamente testar qual dos botões foi clicado e aplicar a regra de negócio conforme cada caso. Este método deve ser adicionado logo após o método onCreate().




Terceiro passo, refatorar o método setOnClickListener() para os dois botões.




Basicamente estamos setando para os dois botões btnAcessar e btnSalvar o método setOnClickListener(). Com esta alteração, a interface OnClickListener() ficara "ouvindo" as ações de click do usuário, e chamará o método onClick() definido no segundo passo.

Note que na linha 43, estamos vinculando o botão btnSalvar ao Widget Button do Layout.

Quarto passo, descobrir qual botão foi clicado pelo usuário.


Neste caso, usaremos a estrutura condicional switch/case para capturar qual botão foi clicado, usando o ID definido para o mesmo na criação do Layout via propriedade android:id.

Adicione a código destacado na imagem abaixo ao seu projeto.




Refatorando as regras de validação para o botão btnAcessar.


A validação consiste em testar se o usuário digitou para os campos Login e Senha as informações corretas, no caso o Login é aula@foo.maddo e a Senha android.




Na linha 88, estamos ativando o botão btnSalvar. Isso acontecerá somente se os campos digitados forem válidos.

Criação dos Pacotes para o Projeto


Talvés você ainda não percebeu, mas a estrutura dos projetos Android é semelhante ao padrão de projeto MVC, que significa Model, View e Controle.

A Model contém as classes em Java, a View contém as telas ou a interface de comunicação entre a aplicação e o usuário e a Controle contém as regras de negócios da aplicação.

Nós iremos criar um pacote para a Model e neste pacote criaremos uma classe chamada Login.java. A vantagem principal será trabalha com Objetos em nosso projeto, isso vai facilitar a manutenção, além de forçar a prática da Progrmação Orientada a Objetos em Java com Android.


Crie um pacote chamado model e adiciona a classe Login.java confome demonstrado nas figuras abaixo:


Criação do Pacote Model






Selecione o pacote foo.maddo.cursoandroidaula10 e click com o botão direito -> New -> Package.


Resultado esperado







Criação da Classe Login.java


Selecione o pacote MODEL, clique com o botão direito -> New -> Java Class e crie a classe Login.Java


Nomeando a Classe





Classe Login.java


A classe Login, conterá apenas três atributos privados, sendo o ID que será gerado toda vez que um registro for incluído ao banco de dados, um atributito String login e por último um atributo String senha. Como esta classe pertence a camada Model, ela não receberá nenhum método adicional a não ser os respectivos gets e sets.






Criação do Pacote DAO - Data Access Object - LoginDAO.Java


Esta camada receberá a classe que terá a função tratar os objetos da camada superior, no caso a VIEW representada pelas Activities Android e enviar para a DataSource para serem gravadas no Banco de Dados. A DAO também será responsável em devolver dados do banco de dados para a VIEW que solicitar.

Nesta aula iremos implementar na classe LoginDAO apenas o método adicionar() do nosso CRUD. Nas próximas aulas estaremos implementando todos os demais métodos.

Crie o pacote DAO e dentro dele a classe LoginDAO.java conforme figura abaixo:





Classe LoginDAO.Java


Esta é a estrutura da classe LoginDAO que será implementada nesta aula. Note que temos o construtor padrão da classe, e um método boleano que recebe o objeto Login na sua assinatura.

Até aqui, esta classe não contém nada de extraordinário, mas iremos "decorar" esta classe com os pré-requisitos Android para permitir a integração da DAO com o SDK Android, especificamente para efetuar a persistência dos dados no SQLite.

É muito importante para o sucesso do seu aprendizado que você perceba a evulução desta aula, se você notar, estamos construindo gradativamente a aplicação, e implementando conforme necessário as alterações na codificação Java comum para outras plataformas de desenvolvimento.




Construtor LoginDAO()


Nosso construtor será responsável em entregar um objeto de banco de dados, vindo da DataSource de forma a permitir que todos os métodos do CRUD tenham disponíveis o acesso aos métodos do SQLite para incluir, alterar, deletar ou listar os dados solicitados pela aplicação.


Método adicionar(Login obj)

Este será o primeiro método do CRUD que será implementado. Estaremos enviando um objeto Login para ser adicionado ao banco de dados. O método adicionar, é do tipo booleano. Caso o objeto seja adicionado com sucesso no Banco de Dados, retorna true, caso contrário retorna falso para a VIEW que notificará o usuário.


Criação do Pacote DataModel


Vamos adicionar mais um pacote ao nosso projeto, neste caso será o pacote DataModel. O papel deste pacote será criar a classe DataModel responsável em manter o que podemos chamar de modelo de dados, ou dicionário de dados do banco de dados, além dos scripts para criar as tabelas no SQLite.




Classe DataModel


Na classe DataModel iremos manter as definições das tabelas que serão usadas pelo Banco de Dados, os nomes dos seus atributos, os seus respectivos tipos de dados e por fim os scripts para criação das tabelas.

Todas as definições serão consumidas pela classe DataSouce, que será a próxima classe a ser implementada dentro do pacote DataSouce.




Significado dos Atributos


  • DB_NAME - Nome do banco de dados
  • TABELA_LOGIN - Nome da tabela "login"
  • ID - Nome do atributo ID
  • LOGIN - Nome do atributo LOGIN
  • SENHA - Nome do atributo SENHA
  • TIPO_TEXTO - Tipo de dados do SQLite para textos, strings, caracteres
  • TIPO_INTEIRO - Tipo de dados do SQLite para valores inteiros
  • TIPO_INTEIRO_PK - Tipo Inteiro e definição para chave primária da tabela 

Métodos 


  • criatTabelaLogin() - Retorna uma string contendo o script SQL para criar a tabela no banco de dados.


Criação do Pacote DataSouce


Este será o último pacote que iremos criar nesta aula. Nele iremos implementar a classe SQLiteOpenHelper do Android, classe responsável pela criação do Banco de Dados.

Crie um novo pacote chamado DataSource -> New -> Packege -> datasource. Em seguida, crie uma classe dentro deste pacote chamada DataSouce.java -> New -> Java Class -> DataSource.java.




Depois de um pouco de trabalho para estruturar nosso projeto nesta aula, finalmente chegamos ao foco da aula, que é implementar um Insert de um objeto no banco de dados SQLite. Todo este esforço vai valer muito a pena, pois ganharemos tempos nas próximas aulas.

Outro detalhes muito importante, é que sem você perceber, criamos uma pequena arquitetura que pode ser aproveitada em outros projetos Android.

Vamos programas nossa classe de persistência de dados, partindo do zero.

Se você criou a classe DataSouce conforme solicitado, sua classe terá a aparencia conforme figura abaixo:



O próximo passo é extender a classe SQLiteOpenHelper.



Note que o compilador reporta um erro, isso se deve pelo fato de sermos obrigados a implementar os métodos da classe SQLiteOpenHelper.

Clique na palavras reservada public e em seguida clique na Lâmpada que o Android Studio irá disponibilizar com algumas sugestões para resolver este erro.



Após surgir as sugestões, clique em Implement methods.



Serão implementados dois métodos, o onCreate() e o onUpgrade().


  • Método onCreate() - Este método será executado apenas uma única vez e caso não existe, criará o banco de dados, conforme as definições definidas na DataModel.
  • Método onUpgrade() - Este método será executado toda vez que a versão do banco de dados for alterada. Em outras palavras, caso ocorra alguma modificação na estrutura do banco de dados, este método será executado e aplicará as alterações necessárias.



Ainda temos que criar o Construtor para a classe DataSource. 









Toda vez que um objeto DataSouce for criado, o construtor espera as seguintes informações:

  • context - Usado para abrir ou criar o banco de dados
  • name - É o nome do banco de dados no sistema de arquivos, caso seja null será criado um banco de dados apenas na memória.
  • factory - Usado para criar um cursor de objetos. Se este valor for null será criado um objeto default.
  • version - Este é o númedo da versão do banco de dados, iniciado por 1. Caso este número seja alterado para 2, significa que a estrutura do banco de dados foi alterada e o método onUpgrade() será executado.

Até aqui, a única informação que temos para o construtor é o nome do banco de dados que foi definido na DataModel. Mas até agora, não é possível acessar esta informação. Devemos adicionar os métodos de acesso gets para todos os atributos da DataModel.

Crie os gets apenas para o atributos selecionados na imagem abaixo:




A classe DataModel deverá ficar conforme demonstrado abaixo:




Podemos utilizar o método getDB_NAME() para informar ao construtor da DataSouce() qual será o nome do banco de dados para a nossa aplicação. Aqui começa a demonstração da vantagem de termos criado a DataModel.









Nos resta informar o context, factory e version. Vamos criar variáveis locais para factory e version. O context será fornecido pela camada de VIEW da aplicação, ou seja, pela classe Activity que desejar persistir algum objeto no banco de dados.




Observe que estamos passando para o construtor da classe extendida SQLiteOpenHelper, o contexto da aplicação, o nome da tabela, que veio da classe DataModel.getDB_NAME(), o valor null para a cursor, e o valor 1 para a versão do banco de dados.

Classe SQLiteDataBase - Criando o banco de dados


Estamos com quase tudo pronto para finalizar criação no banco de dados. Agora necessitamos de um objeto da classe SQLiteDataBase. Será este objeto que nos fornecerá os métodos para ler e escrever no banco de dados, executar insert, upgrade, delete, etc.

Neste momento do curso, não irei aprofundar os conceitos sobre esta classe, o que é assunto de outra aula específica sobre as classes SQLiteOpenHelper e SQLiteDataBase.

Adicione as linhas em destaque abaixo ao seu código Java da classe DataSource.





  • Linha 17 - SQLiteDatabase - Cria um objeto para manipular o banco de dados contendo vários métodos comuns para rotinas de persistência de dados.
  • Linha 23 - Abre o banco de dados para leitura.
  • Linha 30 - Cria caso não exista a tabela Login no banco de dados, a partir das definições da tabela criadas na DataModel.
  • Linha 39 -  Será executada somente se a versão do banco de dados for alterada.

Método para persistência dos dados no banco de dados - persist().


Vamos criar agora um método que não está disponível nativamente no SQLite. O método que iremos criar será chamado de persist(), e sua função será, executar um insert ou um upgrade no banco de dados. O insert é tema desta aula, o upgrade será o tema da próxima aula, porém, já deixaremos o método pronto.



A lógica deste método é baseada no status do atributo ID. Se o mesmo for zero ou nulo, significa que um registro novo deve ser adicionado ao banco de dados, caso contrário, será realizado um upgrade em um registro já existente.

Note que estamos passando o nome da tabela como parâmetro na assinatura deste método, isso torna-o muito reutilizável. Como poderemos ver nesta e nas próximas aulas.

A linha 65, executa o método insert do SQLiteDatabase efetuando a inclusão dos dados no banco de dados.

Observe que temos uma novidade neste método, que é o uso da Classe ContentValues. Esta classe recebe uma lista contendo dois valores,  o primeiro é o nome do campo na tabela, e o segundo é o valor que desejamos gravar para este campo no banco de dados.

Vamos retornar ao método adicionar da classe LoginDAO para preparar os dados para serem incluídos via método persist().


Refatorando a classe LoginDAO()





A classe LoginDAO até o momento contém apenas o método adicionar(). Para que possamos enviar o objeto Login para a DataSouce, teremos que modificar o código Java desta classe.


  • Linha 16 - Estamos criando um objeto DataSource.
  • Linha 17 - Estamos criando um objeto ContentValues, requerido pelo método persist() da DataSource.
  • Linha 19 - Modificamos a assinatura do construtor da classe para receber o contexto da aplicação.
  • Linhas 29 à 32 - Estamos criando uma estância da classe ContentValues e populando o objeto com os dados a serem enviado ao banco de dados.
  • Linha 35 - Estamos executando o método persist() passando como parâmetros os valores a serem salvos e o nome da tabela de destino dos dados no banco de dados.
  • Linha 36 - Setamos o retorno como true, o que significa que os dados foram salvos com sucesso. 

Refatorando as regras de validação para o botão btnSalvar.


O botão btnAcessar é configurado no layout como desabilitado, e somente quando o usuário informar os dados corretamente, o seu status muda de desabilitado para habilitado.

Quando o botão estiver disponível para o usuário, iremos enviar os dados para a camada LoginDAO, que providenciará a preparação do objeto Login para ser gravado no banco de dados.

Se os dados forem salvos corretamente no banco de dados, a troca de tela será efetuada e a tela Dashboard será carregada.





Esta é praticamente a última parte desta aula, onde estamos implementando a regra de negócio para gravar os dados no banco de dados.

Aqui nós criamos um objeto Login, populamos o mesmo com os dados digitados pelo usuário e enviamos para a classe LoginDAO, através do método adicionar().

Como é necessário informar o contexto da aplicação para a DataSouce(), estamos fazendo isso na linha 106. O método getApplicationContext() informa o contexto atual da Activity.

O método adicionar() da classe LoginDAO, irá devolver verdadeiro ou falso, dependerá se ocorreu ou não sucesso ao gravar os dados no banco de dados.

Por último, se tudo estiver correto, trocamos de tela carregando a Dashboard.

Fontes do projeto no GitHub


Os fontes deste projeto estão disponíveis no repositório Git do curso. Para acessar, basta clicar no link abaixo:

https://github.com/profmaddo/CursoAndroidAula10

Conclusão


Persistir dados em um banco de dados é uma das tarefas mais comuns em qualquer sistema, seja ele web, desktop ou mobile. Nesta aula, além de apresentar como criar uma classe para gravar os dados no banco de dados SQLite para Android, também tivemos a oportunidade de aprofundar um pouco mais conceitos importantes sobre separação de regras de negócios em camadas, DataModel, DataSource, DAO e MVC.

Finalizamos a aula com o primeiro método do CRUD implementado. Na próxima aula irei demonstrar como visualizar os dados gravados no banco de dados conforme figura abaixo.