Banco de dados para Android

Cópia fiel de: http://zarelli.wordpress.com/

Banco de dados para android sqlite3

SQLite3

Um Banco de dados é muito útil para qualquer sistema de grande ou pequeno porte, a não ser que seu sistema lida apenas com dados simples, não utilizando de um banco para armazenar informações.

O Android usa o banco de dados SQLite que é open-source, o SQLite é muito utilizado em aplicações populares. Outros exemplo de quem utiliza o SQLite é Mozilla Firefox e iPhone.

No Android o banco de dados que você cria em uma aplicação só é acessível para si mesma, a não ser que você utiliza um provedor de conteúdo (assunto a ser discutido em outro post), uma vez criado o banco de dados, ele é armazenado no diretório “/data/data/{nome do pacote}/databases/{nome do banco}”, alem de gerenciar o banco por código você pode faze-lo pelo adb(clique para saber mais) utilizando a ferramenta sqlite3.

Exemplo:

$ adb -s emulator-5554 shell
# sqlite3 /data/data/zarelli.exemplo/databases/banco
SQLite version 3.3.12
Enter ".help" for instructions
<em>.... enter commands, then quit...</em>
# sqlite> .exit

A Aplicação

Vou implementar um exemplo bem simples sem a utilização de interface, só com visualização no Log. Primeiro vamos definir nosso banco de dados, vou fazer o SQL em um arquivo (diferente de muitos exemplos) e depois carregar no código, eu prefiro assim pois acredito que tem mais controle e fica mais organizado. Após sera implementado as classes de controle do banco e por fim vamos utiliza-las.

Defini a estrutura dos pacotes da seguinte maneira (com suas classes):

No arquivo create.sql vamos definir as tabelas de nosso database:

CREATE TABLE usuarios
(
    id INTEGER PRIMARY KEY autoincrement,
    nome varchar(45) NOT NULL,
    usuario varchar(45) NOT NULL ,
    senha varchar(45) NOT NULL
);

Após a definição do banco vamos criar a classe de mais baixo nível, a BancoManager.java. Essa classe vai ser uma classe abstrata responsável em criar o banco e ter o controle de versão dele, iremos utilizar como classe pai SQLiteOpenHelper.java que é nativa do Android e tem a finalidade de gerenciamento.

public abstract class BancoManager extends SQLiteOpenHelper
{
    protected Context context;

    public BancoManager(Context context, String nome, int versao)
    {
        super(context, nome, null, versao);
        this.context = context;
    }

    public abstract void onCreate(SQLiteDatabase bd);

    public abstract void onUpgrade(SQLiteDatabase bd, int versaoAtual, intversaoNova);

    /** Atravez do id do arquivo sql será gerado o banco de dados.
     *
     * @param fileID
     * @param bd
     * @throws IOException
     */
    protected void byFile(int fileID, SQLiteDatabase bd) throws IOException
    {
        StringBuilder sql = new StringBuilder();
        BufferedReader br = new BufferedReader(newInputStreamReader(context.getResources().openRawResource(fileID)));
        String line;
        while ( (line = br.readLine()) != null )
        {
            line = line.trim();
            if ( line.length() > 0 )
            {
                sql.append(line);
                if ( line.endsWith(";") )
                {
                    bd.execSQL(sql.toString());
                    sql.delete(0, sql.length());
                }
            }
        }
    }
}

Como vemos essa classe não faz nada se ninguém implementar, nela temos um método abstrato onCreate e onUpgrade, ambas precisam ser implementadas para que a coisa toda funcione, o método onCreate ficará responsável em criar o banco, caso o banco já exista nada será alterado, o método onUpgrade é utilizado para atualizar a base da dados, caso alguma tabela seja alterada, mas nada acontece automaticamente devemos implementa-la de forma correta, esse método será chamado automaticamente caso a versão que é passada no contrutor sejá alterada.

Antes de implementar a BancoManager, vamos implementar a classe Banco.java, nela podemos abstrair muita informação, fiz ela o mais simples possível, mas podemos tratar os insert,update,delete,select nesta classe de uma forma bem abstrata para que haja a melhor orientação possível. Entenda que essa classe sera responsável em gerenciar a conexão do banco.

public class Banco
{
    private BancoManager bancoManager;
    private SQLiteDatabase sqld;

    public Banco(BancoManager bancoManager)
    {
        this.bancoManager = bancoManager;
    }

    public void open()
    {
        sqld = bancoManager.getWritableDatabase();
    }

    public SQLiteDatabase get()
    {
        if ( sqld != null && sqld.isOpen() )
        {
            return sqld;
        }
        return null;
    }

    public void close()
    {
        bancoManager.close();
    }
}

Vamos usar a BancoManager.java como explicado anteriormente. Criei o BancoUsuarios.java que irá tratar da criação do nosso banco e atualização.

public class BancoUsuarios extends BancoManager
{
    //nome do banco de dados e versão
    public static final String NAME = "dBusuarios";
    public static final String TAG_LOG = "BancoUsuarios";
    public static final int VERSAO = 1;

    public BancoUsuarios(Context context)
    {
        //defino pelo contrutor do BancoManager a versão e o nome do banco
        super(context, NAME, VERSAO);
    }

    @Override
    public void onCreate(SQLiteDatabase bd)
    {
        criaTabelas(bd);
    }

    /**
     * Este método é chamado automaticamente quando a versão é alterada.
     */
    @Override
    public void onUpgrade(SQLiteDatabase bd, int versaoAtual, int versaoNova)
    {
        //realizaa tratamento de upgrade, caso tenha
        //alteração em tabelas por exemplo.
        Log.e(TAG_LOG, "V.atual: " + versaoAtual);
        Log.e(TAG_LOG, "Nova V.: " + versaoNova);
        //Aqui você deve fazer o tratamento do update do banco.
        //no caso estou apagando minha tabela e criando novamente.
        try
        {
            bd.execSQL("drop table usuarios_tbl;");
        } catch (Exception e)
        {
            Log.e(TAG_LOG, "onUpgrade", e);
        }
        criaTabelas(bd);
    }

    private void criaTabelas(SQLiteDatabase bd)
    {
        try
        {
            //crio o banco de dados atravez do arquivo create.
            byFile(R.raw.create, bd);
        }
        catch (Exception e)
        {
            Log.e(TAG_LOG, "criaTabelas", e);
        }
    }
}

Como vimos implementamos tudo que é necessário para a criação e atualização do banco. Caso alguém não saiba a classe Log.java é responsável em escrever no DDMS(aprenda a usar) que é nosso gerenciador de log de eventos, ninguém que programa em android vive sem o DDMS.

Agora que criamos toda nossa estrutura, construímos nosso alicerce, vamos mostrar nossa classe MainActivity.java por partes, definimos a estrutura da seguinte maneira:.

public class MainActivity extends Activity
{
    public static final String TAG_LOG = "ExemploBanco";
    private Banco banco;

    @Override
    public void onCreate(Bundle savedInstanceState)...

    private void insert(String usuario)...
    private void select()...
    private void update(String usuario, String novo)...
    private void delete(String usuario)...
}

Temos nossa tag de log e nosso Banco definido anteriormente.
O método onCreate vamos fazer toda chamada, iniciar o banco chamar os métodos etc…

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    //inicia e abre banco
    banco = new Banco(new BancoUsuarios(this));
    banco.open();
    //inicia o exemplo (insert,select,update,delete)
    Log.d(TAG_LOG, "\nINSERT");
    //insiro o usuario
    insert("gbzarelli");
    //insiro o usuario
    insert("registro_" + System.currentTimeMillis());
    select();//busco

    Log.d(TAG_LOG, "\nUPDATE");
    String update = "gbzarelli_" + System.currentTimeMillis();
    //atualizo o nome
    update("gbzarelli", update);
    select();//busco

    Log.d(TAG_LOG, "\nDELETE");
    delete(update);//deleto o registro
    select();//busco

    banco.close();//fecha o banco
}

Acredito que até ai não tenha segredo, estamos inserindo dois usuários, um com o parâmetro “gbzarelli” e o outro “registro_xxxxxx” (esse parâmetro vai ser o usuário), após ter inserido fazemos um update mudando o usuário de “gbzarelli” para “gbzarelli_xxxxxx” e por fim fazemos um delete no usuário que foi alterado. Entre essas operações estamos realizando um select para mostrar as informações.

O Insert – Notamos que utilizamos uma classe chamada ContentValues que serve para linkar a coluna com o registro, essa classe é como se fosse um hashmap. Após o registro ser inserido é retornado um long que é respectivo ao id primário da tabela.

private void insert(String usuario)
{
    //inserir dados
    ContentValues cv = new ContentValues();
    cv.put("usuario", usuario);
    cv.put("senha", "147147");
    cv.put("nome_completo", "Guilherme Biff Zarelli");
    long l = banco.get().insert("usuarios_tbl", null, cv);
    Log.i(TAG_LOG, "id insert: " + l);
}

O Select – Aqui usamos  uma query comum, realizada na mão e passamos os parâmetros através de um array de string cada posição é respectiva com a ordem dos pontos de interrogação. Vemos também o uso do Cursor que é referente ao ResultSet utilizado no JavaSE.

private void select()
{
    //O cursor no android é similar ao ResultSet do Java
    Cursor cursor = banco.get().rawQuery("select * from usuarios_tbl limit ?",new String[]{"5"});
    while (cursor.moveToNext())
    {
        Log.i(TAG_LOG, "id: " + cursor.getInt(cursor.getColumnIndex("id_usuarios")));
        Log.i(TAG_LOG, "usuario: " + cursor.getString(cursor.getColumnIndex("usuario")));
        Log.i(TAG_LOG, "senha: " + cursor.getString(cursor.getColumnIndex("senha")));
        Log.i(TAG_LOG, "nomeCompleto: " + cursor.getString(cursor.getColumnIndex("nome_completo")));
        Log.i(TAG_LOG, "-------");
    }
    //Nunca esqueça de fechar o cursor.
    cursor.close();
}

O Update – Também utilizamos o ContentValues e o array de parâmetros

private void update(String usuario, String novo)
{
    ContentValues cv = new ContentValues();
    cv.put("usuario", novo);
    banco.get().update("usuarios", cv, "usuario==?", new String[]{usuario});
}

O Delete – No delete passamos a tabela e a condição e também o array de parâmetros.

private void delete(String usuario)
{
    banco.get().delete("usuarios", "usuario==?", new String[]{usuario});
}

Pronto, na implementação podemos notar que existe várias de maneiras de fazer um select,insert,update ou delete, a classe SQLiteDatabase é bem complexa e cheio de métodos, somente com a prática podemos criar um controle agradável e bem usual. Agora basta estudar e ir aprimorando seu código.

Se rodarmos vamos notar no DDMS mais ou menos o seguinte Log:
Log DDMS banco de dados sqlite3

Caso queiram o projeto segue o link: ProjetoExemploBanco , o projeto foi realizado no NetBeans sobre o Fedora 16 x64 e configurado para a versão 3.2 do Android.

Anúncios

Um comentário em “Banco de dados para Android

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s