Armazenamento em Banco de Dados em Aplicações Android

Propaganda
Armazenamento em Banco de Dados em Aplicações Android Prof. Fellipe Aleixo ([email protected]) Opções de Armazenamento •  Shared Preferences –  Armazenamento de pares chave-­‐valor •  Internal Memory –  UAliza a memória do aparelho •  External Memory –  UAliza algum armazenamento externo como cartão SD, USB, etc. •  Banco de Dados SQLite •  Mecanismo de banco de dados para o qual o Android oferece suporte naAvo •  Obs.: banco de dados pode ser criados e acessados por qualquer classe de uma aplicação (apenas) O que é SQLite? •  Trata-­‐se de uma biblioteca de soQware um motor de banco de dados SQL •  CaracterísAcas: –  Self-­‐contained –  Serverless –  Zero-­‐configura:on –  Transac:onal –  Open Source SQLite no Android •  Nenhum banco de dados padrão é oferecido para a sua aplicação Android •  A própria aplicação precisa criar o banco de dados, tabelas, índices e popular os dados SQLite no Android •  Para criar e manipular banco de dados a maneira recomendada é criar uma subclasse de SQLiteOpenHelper e definir os métodos: –  Construtor –  onCreate() –  onUpgrade() •  Métodos opcionais: –  onOpen() –  onDowngrade() Construtor da Classe Helper •  Exemplo: public class DicAonaryOpenHelper extends SQLiteOpenHelper { private staAc final String DATABASE_NAME = “meu_bd”; private staAc final int DATABASE_VERSION = 1; DicAonaryOpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } } –  SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) Método onCreate() public class DicAonaryOpenHelper extends SQLiteOpenHelper { private staAc final String DATABASE_NAME = “meu_bd”; private staAc final int DATABASE_VERSION = 2; private staAc final String DICTIONARY_TABLE_CREATE = “CREATE TABLE DICTIONARY (KEYWORD TEXT,” + “ DEFINITION TEXT);”; DicAonaryOpenHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DICTIONARY_TABLE_CREATE); } } Método onUpgrade() ... ... @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS DICTIONARY"); onCreate(db); } Uma vez criado o banco de dados, este pode ser acessado a parAr dos COMPONENTES GRÁFICOS Acessando o Banco de Dados package exemplo.aula; import android.app.AcAvity; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; public class HelloBDAcAvity extends AcAvity { private SQLiteDatabase database; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); DatabaseHelper helper = new DatabaseHelper(this); database = helper.getReadableDatabase(); } } Manipulando o Banco de Dados 1)  UAlizar o método execSQL() –  Para executar qualquer SQL que não retorna resultados (INSERT, UPDATE e DELETE) 2)  UAlizar os métodos insert(), update() e delete() –  Não é necessário trabalhar diretamente com SQL package exemplo.aula; import android.app.AcAvity; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; public class HelloBDAcAvity extends AcAvity { private SQLiteDatabase database; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); DatabaseHelper helper = new DatabaseHelper(this); database = helper.getWritebleDatabase(); database.execSQL("INSERT INTO DICTIONARY ”+ “(KEYWORD,DEFINITION) VALUES “+ “('Android','Plataforma para DisposiAvos Móveis')"); } } UAlizando Métodos Específicos •  Não uAlizando SQL diretamente private void processAdd(DialogWrapper wrapper) { ContentValues values = new ContentValues(2); values.put(DatabaseHelper.TITLE, wrapper.getTitle()); values.put(DatabaseHelper.VALUE, wrapper.getValue()); db.getWritableDatabase().insert("constants", null, values); } private void processDelete(long rowId) { String[] args = { String.valueOf(rowId) }; db.getWritableDatabase().delete("constants", "ID=?", args); } Buscando Dados no Banco 1)  Através do método rawQuery() –  Permite a execução de um uma consulta SQL 2)  Através do método query() –  Não necessita trabalhar diretamente com SQL –  São informados os critérios uAlizados na busca UAlizando o método rawQuery() •  Informando a consulta SQL completa: database=db.getReadableDatabase(); Cursor constantsCursor; constantsCursor = database.rawQuery(“SELECT _ID, Atle, value “+ “FROM constants “+ “ORDER BY Atle", null); UAlizando o método query() •  Parâmetros para compor a consulta: –  O nome da tabela –  A lista de colunas a serem retornadas –  A cláusula WHERE (pode informar parâmetros) –  Lista dos valores para subsAtuir os parâmetros –  A cláusula GROUP BY –  A cláusula HAVING –  A cláusula ORDER BY UAlizando o método query() String[] columns={"ID", "inventory"}; String[] parms={"snicklefritz"}; Cursor result = db.query("widgets", columns, "name=?", parms, null, null, null); –  Tabela “widgets” –  Colunas desejadas: “ID” e “inventory” –  WHERE name = ? –  Parâmetro “snicklefritz” Manipulando Cursores •  O resultado de uma consulta é um cursor –  Apontador para os registros resultantes –  Permite a navegação pelos resultados Manipulando Cursores •  Métodos para manipulação de um cursor: –  getCount() à número de registros retornados –  Navegar pelos registros – moveToFirst(), moveToNext() e isAPerLast() –  getColumnNames() e getColumnIndex() à recupera nomes e posição das culunas –  requery() à reexecuta a consulta –  close() à libera os recursos Manipulando Cursores Cursor result = db.rawQuery(“SELECT ID, name, inventory “+ “FROM widgets", null); while (!result.moveToNext()) { int id = result.getInt(0); String name = result.getString(1); int inventory = result.getInt(2); // Faz algo com os valores ... } result.close(); Vamos PRATICAR Construir uma Aplicação Exemplo •  Aplicação: agenda de contatos –  Um contato possui nome, e-­‐mail e telefone –  Os contatos devem ser armazenados no banco Passo-­‐a-­‐Passo 1)  Criar um projeto com o nome de “Contatos” –  Pacote: exemplo.contatos –  AAvidade: ContatosAcAvity 2)  Criar uma classe com o nome “DbHelper” –  Responsável por criar o banco de dados –  Estende a classe SQLiteOpenHelper import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.uAl.Log; public class DbHelper extends SQLiteOpenHelper { ... } Passo-­‐a-­‐Passo 3)  Definição de constantes private staAc final String DATABASE_NAME = “contatosDB”; private staAc final int DATABASE_VERSION = 1; public staAc final String TABLE_NAME = ”contatos”; public staAc final String ID = "_id"; public staAc final String NOME = "nome"; public staAc final String EMAIL = "email"; public staAc final String TELEFONE = "telefone"; public staAc final String FOTO = "foto"; private staAc final String DATABASE_CREATE = "create table “+ TABLE_NAME + “( “+ ID +" integer primary key autoincrement, " + NOME + " text not null, " + EMAIL + " text not null, ” + TELEFONE+" text not null, " + FOTO +" BLOB);"; Passo-­‐a-­‐Passo 4)  Definição do construtor public DbHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } Passo-­‐a-­‐Passo 5)  Definição dos métodos onCreate() e onUpgrade() @Override public void onCreate(SQLiteDatabase db) { db.execSQL(DATABASE_CREATE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVers, int newVers) { Log.w(DbHelper.class.getName(), "Upgrading database from “+oldVers+” to “+newVers); db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } Passo-­‐a-­‐Passo 6)  Criar a classe DBAdpter para concentrar o trabalho com o banco de dados import java.io.ByteArrayOutputStream; import java.uAl.ArrayList; import java.uAl.List; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.SQLExcepAon; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.BitmapFactory; public class DBAdapter { ... } Passo-­‐a-­‐Passo 7)  Declarar atributos e construtor da classe DBAdpter private SQLiteDatabase database; private DbHelper dbHelper; private String[] allColumns = { DbHelper.ID, DbHelper.NOME, DbHelper.EMAIL, DbHelper.TELEFONE, DbHelper.FOTO}; public DBAdapter(Context context) { dbHelper = new DbHelper(context); } Passo-­‐a-­‐Passo 8)  Definir um método que insere um contato no banco de dados –  Veja no próximo slide public Contacto createContacto(String nome, String email, String telefone, Bitmap foto) { ContentValues values = new ContentValues(); values.put(DB.NOME, nome); values.put(DB.EMAIL,email); values.put(DB.TELEFONE,telefone); ByteArrayOutputStream baos = new ByteArrayOutputStream(); foto.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] photo = baos.toByteArray(); values.put(DB.FOTO, photo); long insertId = database.insert(DB.TABLE_NAME, null, values); Cursor cursor = database.query(DB.TABLE_NAME, allColumns, DB.ID + " = " + insertId, null,null, null, null); cursor.moveToFirst(); return cursorToContato(cursor); } Passo-­‐a-­‐Passo 9)  Criar uma classe Contato com os atributos, construtor com parâmetros e métodos acessadores e modificadores 10) Definir um método para remover um contato public void removeContato (int idContato) { database.delete(DbHelper.TABLE_NAME, DbHelper.ID + " = " + idContato, null); } Passo-­‐a-­‐Passo 11) Definir um método para retornar um contato passando um cursos para o mesmo private Contato cursorToContato(Cursor cursor) { byte[] blob = cursor.getBlob(cursor.getColumnIndex(DB.FOTO)); Bitmap bmp = BitmapFactory.decodeByteArray(blob, 0, blob.length); Contato contato = new Contato(cursor.getLong(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), bmp); return contato; } Passo-­‐a-­‐Passo 12) Definir um método retornando os contatos public List<Contato> getContatos() { Cursor cursor = database.rawQuery("select * from contatos", null); ArrayList<Contato> contatos = new ArrayList<Contato>(); cursor.moveToFirst(); while(!cursor.moveToNext()) { Contato atual = new Contato(cursor.getLong(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), bmp); contatos.add(atual); } return contatos; } Passo-­‐a-­‐Passo 13) Definir um método que retorna um contato passando o idenAficador do mesmo public Contato getContato (int idContato){ Cursor cursor = database.query(DB.TABLE_NAME, allColumns, DB.ID + " = " + idContato, null,null, null, null); cursor.moveToFirst(); return cursorToContato(cursor); } Passo-­‐a-­‐Passo 14) Crie as classes de Layout para operando com estas classes criada implemente a funcionalidade de agenda de contatos... 
Download