Capítulo 04: Persistência com SQLite Instrutor ● Programador desde 2000 ● Aluno de doutorado ● ● ● ● Mestre em informática pelo ICOMP/UFAM Especialista em aplicações WEB – FUCAPI [email protected] sites.google.com/site/marcio palheta M.Sc. Márcio Palheta Agenda ● MVC em Android ● Criação da camada de modelo - entidade Aluno ● Padrão de Projeto – View Helper ● Padrão de Projeto – Data Access Object (DAO) ● CRUD (Create, Read, Update, Delete) M.Sc. Márcio Palheta 3/90 Model View Controller - MVC Activities (.java) CONTROLLER VIEW Layouts (.xml) MODEL DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 4/90 Model View Controller - MVC Activities (.java) Evento CONTROLLER Chamada de metodo() modelo.getEstado() VIEW Layouts (.xml) MODEL DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 5/90 Model View Controller - MVC Activities (.java) Evento CONTROLLER Chamada de metodo() modelo.getEstado() VIEW Layouts (.xml) MODEL SQLite DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 6/90 Model View Controller - MVC Activities (.java) Evento CONTROLLER Chamada de metodo() Exibir tela modelo.getEstado() VIEW Layouts (.xml) MODEL SQLite DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 7/90 Model View Controller - MVC Activities (.java) Evento Entrada de dados CONTROLLER Chamada de metodo() Exibir tela modelo.getEstado() VIEW Layouts (.xml) MODEL SQLite DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 8/90 Model View Controller - MVC Activities (.java) Evento Entrada de dados CONTROLLER Chamada de metodo() modelo.atualizarEstado() Exibir tela modelo.getEstado() VIEW Layouts (.xml) MODEL SQLite DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 9/90 Model View Controller - MVC Activities (.java) Evento Entrada de dados CONTROLLER Chamada de metodo() modelo.atualizarEstado() Exibir tela modelo.getEstado() MODEL VIEW Layouts (.xml) Notificação de mudanças SQLite DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 10/90 Model View Controller - MVC Activities (.java) Evento Entrada de dados Exibir tela CONTROLLER tela.atualizarVisao() Chamada de metodo() modelo.atualizarEstado() modelo.getEstado() MODEL VIEW Layouts (.xml) Notificação de mudanças SQLite DAO(.java) Entidades(.java) M.Sc. Márcio Palheta 11/90 Persistência com SQLite ● ● ● A tela de Listagem da nossa App permite o cadastro do nome dos alunos e os exibe em uma ListView Contudo, temos alguns problemas nessa abordagem: – Os dados são perdidos quando a App é destruída – Precisamos de outros dados para o Aluno Como resposta, poderíamos: – Persistir os dados em um Bando de Dados – Usar a tela de Formulário para cadastro e alteração de dados do Aluno M.Sc. Márcio Palheta 12/90 Exercício 01: Crie o JavaBean Aluno M.Sc. Márcio Palheta 13/90 Exercício 01: implemente o bean Aluno M.Sc. Márcio Palheta 14/90 Pensando na arquitetura do sistema ● Agora, no método onCreate() da nossa Activity, precisamos povoar um objeto Aluno com dados da tela: M.Sc. Márcio Palheta 15/90 Pensando na arquitetura do sistema ● Agora, no método onCreate() da nossa Activity, campos da tela precisamos povoar um objeto Aluno com AAssocia dados da tela: referências de controle M.Sc. Márcio Palheta 16/90 Pensando na arquitetura do sistema ● Agora, no método onCreate() da nossa Activity, campos da tela precisamos povoar um objeto Aluno comAAssocia dados da tela: referências de controle Criação de um objeto Aluno M.Sc. Márcio Palheta 17/90 Pensando na arquitetura do sistema ● Agora, no método onCreate() da nossa Activity, campos da tela precisamos povoar um objeto Aluno comAAssocia dados da tela: referências de controle Criação de um objeto Aluno Povoar o novo Aluno com dados vindos da tela M.Sc. Márcio Palheta 18/90 Pensando na arquitetura do sistema ● ● ● ● A complexidade da Activity aumenta, à medida que novas funcionalidades forem implementadas É uma boa prática de programação isolarmos pequenas responsabilidades em outras classes Assim, a Activity passa a realizar o seu trabalho interagindo com pequenos especialistas Neste cenário, podemos implementar o padrão de projeto View Helper, que define a criação de classes especialistas em extrair e tratar dados das telas M.Sc. Márcio Palheta 19/90 Exercício 02: A classe Helper M.Sc. Márcio Palheta 20/90 Exercício 02: A classe Helper Novo pacote para guardar nossos Helpers M.Sc. Márcio Palheta 21/90 Exercício 02: A classe Helper Novo pacote para guardar nossos Helpers Clase Helper para o nosso formulário M.Sc. Márcio Palheta 22/90 Exercício 02: A classe Helper Novo pacote para guardar nossos Helpers Clase Helper para o nosso formulário Atributos que representam componentes de tela M.Sc. Márcio Palheta 23/90 Exercício 02: A classe Helper Novo pacote para guardar nossos Helpers Clase Helper para o nosso formulário Atributos que representam componentes de tela Atributo que que armazena a referência a um Aluno M.Sc. Márcio Palheta 24/90 Exercício 02: A classe Helper (continuação) ● Método construtor que recebe um FormularioActivity M.Sc. Márcio Palheta 25/90 Exercício 02: A classe HelperO construtor (continuação) recebe um FormularioActivity ● Método construtor que recebe um FormularioActivity M.Sc. Márcio Palheta 26/90 Exercício 02: A classe HelperO construtor (continuação) recebe um Associa atributos do helper ● a Método componentes de tela construtor FormularioActivity que recebe um FormularioActivity M.Sc. Márcio Palheta 27/90 Exercício 02: A classe HelperO construtor (continuação) recebe um Associa atributos do helper ● a Método componentes de tela construtor FormularioActivity que recebe um FormularioActivity Criação do objeto Aluno M.Sc. Márcio Palheta 28/90 Exercício 02: A classe Helper ( Final ) M.Sc. Márcio Palheta 29/90 Exercício 02: A classe Helper ( Final ) Método que retorna Aluno com dados vindos da Tela M.Sc. Márcio Palheta 30/90 Exercício 02: A classe Helper ( Final ) Método que retorna Aluno com dados vindos da Tela Seta os atributos do Aluno com campos da Tela M.Sc. Márcio Palheta 31/90 Exercício 02: A classe Helper ( Final ) Método que retorna Aluno com dados vindos da Tela Seta os atributos do Aluno com campos da Tela Retorna uma referência para um objeto Aluno M.Sc. Márcio Palheta 32/90 Usando o Helper ● Agora que nossa classe FormularioHelper está pronta, podemos utilizá-la na nossa classe de controle FormularioActivity ● Para isso, vamos criar um atributo FormularioHelper ● Criar um objeto Helper no método onCreate() ● ● Utilizar os dados do Aluno em qualquer método que necessite desse objeto (reuso) Em nosso exemplo, usaremos o click do botão para exibir o nome do aluno M.Sc. Márcio Palheta 33/90 Exercício 03: Usando o Helper na View M.Sc. Márcio Palheta 34/90 Exercício 03: Usando o Helper na View Definição do novo atributo FormularioHelper M.Sc. Márcio Palheta 35/90 Exercício 03: Usando o Helper na View Definição do novo atributo FormularioHelper Inicialização do helper, passando uma referência para o objeto atual(this) M.Sc. Márcio Palheta 36/90 Exercício 03: Usando o Helper na View Definição do novo atributo FormularioHelper Inicialização do helper, passando uma referência para o objeto atual(this) Pedindo do Helper uma referência a Aluno M.Sc. Márcio Palheta 37/90 Exercício 03: Usando o Helper na View Definição do novo atributo FormularioHelper Inicialização do helper, passando uma referência para o objeto atual(this) Pedindo do Helper uma referência a Aluno Usando o novo objeto Aluno M.Sc. Márcio Palheta 38/90 Chegou a hora da persistência ● O ViewHelper extrai os dados de Aluno da tela ● Vamos armazenar esses dados em um Banco de Dados ● O Android vem com o banco relacional SQLite ● ● ● Para converter Objetos Java em Relações do banco de dados, vamos utilizar o padrão de projeto DAO DAO (Data Access Object) define que, para cada tabela do banco, criamos uma classe de perssitência Ex: para a tabela Aluno, teremos uma classe AlunoDAO, responsável pelo CRUD do aluno M.Sc. Márcio Palheta 39/90 Exercício 04: Classe AlunoDAO ● Crie a classe para persistir dados do Aluno: M.Sc. Márcio Palheta 40/90 Exercício 04: Classe AlunoDAO ● Novo pacote para classes de persistência Crie a classe para persistir dados do Aluno: M.Sc. Márcio Palheta 41/90 Exercício 04: Classe AlunoDAO ● Novo pacote para classes de persistência Crie a classe para persistir dados do Aluno: Classe DAO para persistir dados de Alunos M.Sc. Márcio Palheta 42/90 Exercício 04: Classe AlunoDAO ● Novo pacote para classes de persistência Crie a classe para persistir dados do Aluno: Classe DAO para persistir dados de Alunos Filha da classe de persistência SQLiteOpenHelper M.Sc. Márcio Palheta 43/90 Mas nem tudo são flores ● ● ● ● Até o momento da elaboração deste treinamento, não havia um framework estável para tratar o Mapeamento Objeto Relacional (vulgo MOR) em Android Dito isto, só nos resta fazer o controle manual das versões do nosso Banco de Dados Vamos atualizar nossa classe AlunoDAO para inclusão de algumas constantes necessárias ao nosso controle de versões Em seguida, vamos começar a usar as constantes no construtor da classe AlunoDAO M.Sc. Márcio Palheta 44/90 Exercício 05: Controle de versão do BD M.Sc. Márcio Palheta 45/90 Exercício 05: Controle de versão do para BD Novas constantes controle manual de versão do BD M.Sc. Márcio Palheta 46/90 Exercício 05: Controle de versão do para BD Novas constantes controle manual de versão do BD Registro da TAG de log padrão da nossa APP M.Sc. Márcio Palheta 47/90 Exercício 05: Controle de versão do para BD Novas constantes controle manual de versão do BD Registro da TAG de log padrão da nossa APP Método construtor que recebe apenas o Contexto M.Sc. Márcio Palheta 48/90 Exercício 05: Controle de versão do para BD Novas constantes controle manual de versão do BD Registro da TAG de log padrão da nossa APP Método construtor que recebe apenas o Contexto Chamada ao construtor da classe pai M.Sc. Márcio Palheta 49/90 Criação e atualização do BD ● ● ● ● Uma vez que o nosso controle de versão ocorre de forma manual, precisamos de métodos para criar e atualizar a estrutura das tabelas do nosso BD O método onCreate(SQLiteDatabase database) é invocado sempre que uma tabela não existir na base. Já o método onUpgrade(SQLiteDatabase database, int versaoAntiga, int versaoNova) é chamado quando precisamos atualizar a estrutura das tabelas Na nossa App, usaremos o OnUpgrade() para apagar e reconstruir a base M.Sc. Márcio Palheta 50/90 Exercício 06: Criação de tabelas ● Na classe AlunoDAO, crie o método onCreate(): M.Sc. Márcio Palheta 51/90 Exercício 06: Criação de tabelas ● Na classe AlunoDAO, crie o método onCreate(): Definição do comando que será executado M.Sc. Márcio Palheta 52/90 Exercício 06: Criação de tabelas ● Na classe AlunoDAO, crie o método onCreate(): Definição do comando que será executado Execução da atualização do banco de dados M.Sc. Márcio Palheta 53/90 Exercício 07: Atualização de tabelas ● Na classe AlunoDAO, crie o método onUpdate(): M.Sc. Márcio Palheta 54/90 Exercício 07: Atualização de tabelas ● Na classe AlunoDAO, crie o método onUpdate(): M.Sc. Márcio Palheta 55/90 Exercício 08: AlunoDAO.cadastrar() M.Sc. Márcio Palheta 56/90 Método que recebe um objeto Aluno e salva seus dados no BD Exercício 08: AlunoDAO.cadastrar() M.Sc. Márcio Palheta 57/90 Método que recebe um objeto Aluno e salva seus dados no BD Objeto que guarda os Exercício 08:usados AlunoDAO.cadastrar() valores que serão para salvar no BD M.Sc. Márcio Palheta 58/90 Método que recebe um objeto Aluno e salva seus dados no BD Objeto que guarda os Exercício 08:usados AlunoDAO.cadastrar() valores que serão para salvar no BD Povoando o mapa de valores com [chave:valor] M.Sc. Márcio Palheta 59/90 Método que recebe um objeto Aluno e salva seus dados no BD Objeto que guarda os Exercício 08:usados AlunoDAO.cadastrar() valores que serão para salvar no BD Povoando o mapa de valores com [chave:valor] Armazena os dados do Aluno no banco M.Sc. Márcio Palheta 60/90 Atualização da FormularioActivity ● ● Agora que nossa camada de modelo está prepara para o cadastro do aluno, podemos atualizar nossa tela de formulário; No click do botão de Salvar, vamos: – Pedir um objeto Aluno do Helper; – Abrir uma conexão com BD, criando AlunoDAO; – Cadastrar o novo Aluno no BD; e – Fechar a conexão com o banco de dados M.Sc. Márcio Palheta 61/90 Exercício 09: Botão salvar M.Sc. Márcio Palheta 62/90 Exercício 09: Botão salvar M.Sc. Márcio Palheta 63/90 Queremos ver o que foi salvo ● ● ● ● Para visualizar os dados do banco de dados, precisamos atualizar as camadas de visão, controle e modelo Na camada de modelo, vamos criar o método listar() Vamos remover o EditText e Button das camadas de visão e controle Na camada de controle, precisamos alterar o método onCreate() da ListaAlunosActivity para chamar o método listar() da camada de modelo e apagar os métodos: – onSaveInstanceState() e onRestoreInstanceState() M.Sc. Márcio Palheta 64/90 Exercício 10: método AlunoDAO.listar() ● Início do método para recuperar Alunos do BD M.Sc. Márcio Palheta 65/90 Exercício 10: método AlunoDAO.listar() ● Início do método para recuperar Alunos do BD Instrução SQL para buscar todos os Alunos M.Sc. Márcio Palheta 66/90 Exercício 10: método AlunoDAO.listar() ● Início do método para recuperar Alunos do BD Instrução SQL para buscar todos os Alunos O Android recupera os registros do SQLite em um Cursor M.Sc. Márcio Palheta 67/90 Exercício 10: método AlunoDAO.listar() ● Início do método para recuperar Alunos do BD Instrução SQL para buscar todos os Alunos O Android recupera os registros do SQLite em um Cursor Vetor de parâmetros da consulta SQL M.Sc. Márcio Palheta 68/90 Exercício 10: final do método listar() M.Sc. Márcio Palheta 69/90 Percorre todos os registros do Cursor Exercício 10: final do método listar() M.Sc. Márcio Palheta 70/90 Percorre todos os registros do Cursor Exercício 10: final do método listar() Carrega o objeto Aluno com campos do Cursor M.Sc. Márcio Palheta 71/90 Percorre todos os registros do Cursor Exercício 10: final do método listar() Carrega o objeto Aluno com campos do Cursor Adiciona o Aluno à coleção de resposta M.Sc. Márcio Palheta 72/90 Percorre todos os registros do Cursor Exercício 10: final do método listar() Carrega o objeto Aluno com campos do Cursor Adiciona o Aluno à coleção de resposta android.database.SQLException É filha de RuntimeException M.Sc. Márcio Palheta 73/90 Percorre todos os registros do Cursor Exercício 10: final do método listar() Carrega o objeto Aluno com campos do Cursor Adiciona o Aluno à coleção de resposta android.database.SQLException É filha de RuntimeException Garante o fechamento da conexão com BD M.Sc. Márcio Palheta 74/90 Exercício 11: Crie Aluno.toString() M.Sc. Márcio Palheta 75/90 Exercício 12: Atualização da Tela inicial ● Altere o arquivo: /res/layout/listaalunoslayout.xml ● Deixe apenas a ListView M.Sc. Márcio Palheta 76/90 Exercício 13: camada de controle ● No método onCreate() da ListaAlunosActivity, deixe apenas a associação da ListView M.Sc. Márcio Palheta 77/90 Exercício 13: camada de controle ● No método onCreate() da ListaAlunosActivity, deixe apenas a associação da ListView Vamos manter a associação entre view e controller M.Sc. Márcio Palheta 78/90 Exercício 13: camada de controle ● No método onCreate() da ListaAlunosActivity, deixe apenas a associação da ListView Vamos manter a associação entre view e controller O código para carga da coleção de alunos ficará em outro método M.Sc. Márcio Palheta 79/90 Exercício 14: Mudança de tipos ● ● Nossa coleção de Alunos deve deixar de ser List<String> e se tornar List<Aluno> Altere, também, o tipo do ArrayAdapter M.Sc. Márcio Palheta 80/90 Exercício 14: Mudança de tipos ● ● Nossa coleção de Alunos deve deixar de ser List<String> e se tornar List<Aluno> Altere, também, o tipo do ArrayAdapter M.Sc. Márcio Palheta 81/90 Exercício 15: carga dos dados ● Na ListaAlunosActivity, crie o método carregarLista() para acesso ao DAO e carga da coleção de Alunos M.Sc. Márcio Palheta 82/90 Exercício 15: carga dos dados ● Na ListaAlunosActivity, crie o método carregarLista() para Novo método para acesso ao DAO e carga da coleção de Alunos carga da coleção de alunos M.Sc. Márcio Palheta 83/90 Exercício 15: carga dos dados ● Na ListaAlunosActivity, crie o método carregarLista() para Novo método para acesso ao DAO e carga da coleção de Alunos carga da coleção de alunos Acesso à camada de modelo M.Sc. Márcio Palheta 84/90 Exercício 15: carga dos dados ● Na ListaAlunosActivity, crie o método carregarLista() para Novo método para acesso ao DAO e carga da coleção de Alunos carga da coleção de alunos Acesso à camada de modelo Atualização da tela M.Sc. Márcio Palheta 85/90 Exercício 16: Carga no onResume() ● ● Na classe ListaAlunosActivity, vamos cria o método onResume() Nesse método, vamos fazer a chamada a carregarLista() M.Sc. Márcio Palheta 86/90 Execute a nossa App M.Sc. Márcio Palheta 87/90 O que vem a seguir? ● Complemento do cadastro - exclusão (ContextMenu) ● Compartilhar informações entre Activities – Intents ● Intent implicita – Chamada telefônica para um aluno ● Envio e Recebimento de SMS ● Navegar em site do Aluno e Envio de email ● Câmera e arquivos ● LayoutInflater ● Serviços de background ● Integração via JSON M.Sc. Márcio Palheta 88/90 Referências ● www.caelum.com.br ● d.android.com ● ● LECHETA, Ricardo. Google Android, 3a edição, Novatec, São Paulo, 2013 Código fonte completo: https://github.com/marciopalheta/cursosandroid M.Sc. Márcio Palheta 89/90 Capítulo 04: Persistência com SQLite