Como Usar SQLite em Aplicações Android

Este post utiliza o SQLite para demonstrar como manipular informações em um Banco de Dados no Android. Foi criado um projeto para armazenar as informações de livros, tais como titulo, autor, ano de publicação e gênero. O projeto permite visualizar os livros cadastrados, inserir, alterar e excluir livros.

O projeto é composto pelas seguintes classes:
  • Livro: Classe  onde estão definidos os parâmetros do livro.
  • SQLiteHelper: Classe utilizada na criação e atualização do banco de dados.
  • LivroDb: Classe utilizada nas operações de consulta, inclusão e exclusão de livros.
  • Principal: Classe responsável pela tela inicial da aplicação.
  • VisualizarActivity: Classe responsável pela tela que exibe a relação de livros cadastrados na base de dados.
  • AlterarActivity: Classe responsável pela tela de alteração dos dados dos livros.
  • InsertActivity: Classe responsável pela tela de inserção do livro na base dados.
A Classe Livro é utilizada para manipular os parâmetros dos livros. Esta classe possui como parâmetros as mesmas colunas definidas na base de dados e implementa a interface Serializable que permite a serialização e deserialização da classe. Esta funcionalidade é utilizada para passar o objeto lista de livros de um Intent para outro, necessário na classe Principal, quando é necessário navegar da tela principal para a tela de visualização de livros.

public class Livro implements Serializable {
    private static final long serialVersionUID = -8666122216249625117L;
    private int id;
    private String titulo;
    private String autor;
    private String anoPublicacao;
    private String genero;
    private String[] livrosColumns;
    
    public String[] getLivrosColumns() {
        livrosColumns = new String[] {"_id", "titulo", "autor",
                "ano_publicacao", "genero"                
        };
        return livrosColumns;
    }    
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getTitulo() {
        return titulo;
    }
    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }
    public String getAutor() {
        return autor;
    }
    public void setAutor(String autor) {
        this.autor = autor;
    }
    public String getAnoPublicacao() {
        return anoPublicacao;
    }
    public void setAnoPublicacao(String anoPublicacao) {
        this.anoPublicacao = anoPublicacao;
    }
    public String getGenero() {
        return genero;
    }
    public void setGenero(String genero) {
        this.genero = genero;
    }
}


A Classe SQLiteHelper herda  da classe SQLiteOpenHelper e possui os métodos OnCreate(SQLiteDatabase) que cria a base de dados juntamente com a tabela livros e o método OnUpgrade(SQLiteDatabase, int, int) que faz a atualização da base de dados SQLite no caso de uma alteração no metadata da base, por exemplo em uma situação de criação de uma nova coluna.

public class SQLiteHelper extends SQLiteOpenHelper {
    public static final String TAG = "SQLiteHelper";
    public static final String DATABASE_NAME = "livros";
    public static final int DATABASE_VERSION = 1;
    private String scriptSQLCreate;
    private String scriptSQLDelete;
    
    public SQLiteHelper(Context context, String databaseName, 
            int databaseVersion, String scriptSQLCreate, 
            String scriptSQLDelete){
        super(context, databaseName, null, databaseVersion);
        this.scriptSQLCreate = scriptSQLCreate;
        this.scriptSQLDelete = scriptSQLDelete;    
    }

    /**
     * Cria a base de dados.
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        try {
            db.execSQL(scriptSQLCreate);
        } catch (SQLException e) {
            Log.e(TAG, e.toString());            
        }
    }

    /**
     * Faz o upgrade da base de dados.
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, 
            int newVersion) {
        try {
            // Exclui a tabela anterior
            db.execSQL(scriptSQLDelete);
            // Cria a nova tabela
            onCreate(db);
        } catch (SQLException e) {
            Log.e(TAG, e.toString());
        }
    }
}


A classe LivroDb  é composta pelos métodos:
  • LivroDb(Context): Construtor da classe que cria ou abre a base de dados se a mesma já foi criada.
  • close(): Fecha a base de dados se estiver aberta.
  • selectLivros(): Faz um busca na tabela livros retornando uma lista dos livros existentes na base de dados.
  • contentLivro(Livro): Utiliza a classe ContentValues para associar a coluna da tabela livros com o seu respectivo valor.
  • insertLivro(Livro): Insere um livro na base de dados.
  • excluirLivro(Livro): Exclui um livro da base de dados.
  • alterarLivro(Livro): Altera os dados do livro na base de dados.
public class LivroDb{
    private static final String TAG = "LivroDb";
    private static final String SCRIPT_DELETE_DATABASE = 
        "DROP TABLE IF EXISTS livros";

    private static final String SCRIPT_CREATE_DATABASE =
        "CREATE TABLE livros (" +
        "_id INTEGER NOT NULL PRIMARY KEY," + 
        "titulo TEXT," + 
        "autor TEXT," + 
        "ano_publicacao TEXT," + 
        "genero TEXT)";
    private static final String TABLE_NAME = "livros";
    private SQLiteHelper dbHelper;
    private SQLiteDatabase db;
    private List<Livro> livros;    
    
    public LivroDb(Context ctx){
        try {
            dbHelper = new SQLiteHelper(ctx, SQLiteHelper.DATABASE_NAME,
                    SQLiteHelper.DATABASE_VERSION, 
                    LivroDb.SCRIPT_CREATE_DATABASE,
                    LivroDb.SCRIPT_DELETE_DATABASE);

            livros = new ArrayList<Livro>();
            
            // Cria ou abre a base de dados
            db = dbHelper.getWritableDatabase();
            
        } catch (SQLiteException e) {
            Log.e(TAG, e.toString());
        }

    }
    
    public void close(){
        if (db != null) {
            if (db.isOpen() == true) {
                db.close();
            }
        }
    }
    
    public List<Livro> selectLivros(){
        Cursor cursor = null;
        livros.clear();
        try {
            cursor = db.query(LivroDb.TABLE_NAME, new Livro().getLivrosColumns(), 
                    null, null, null, null, null);
            
            if (cursor.getCount() > 0) {
                while (cursor.moveToNext()) {
                    Livro livro = new Livro();
                    
                    if (!cursor.isNull(cursor.getColumnIndex("_id"))) {
                        livro.setId(cursor.getInt(cursor.getColumnIndex("_id")));
                    }
                    
                    if (!cursor.isNull(cursor.getColumnIndex("titulo"))) {
                        livro.setTitulo(cursor.getString(
                                cursor.getColumnIndex("titulo")));
                    }
                    
                    if (!cursor.isNull(cursor.getColumnIndex("autor"))) {
                        livro.setAutor(cursor.getString(
                                cursor.getColumnIndex("autor")));
                    }
                    
                    if (!cursor.isNull(cursor.getColumnIndex("ano_publicacao"))) {
                        livro.setAnoPublicacao(cursor.getString(
                                cursor.getColumnIndex("ano_publicacao")));
                    }
                    
                    if (!cursor.isNull(cursor.getColumnIndex("genero"))) {
                        livro.setGenero(cursor.getString(
                                cursor.getColumnIndex("genero")));
                    }
                    
                    livros.add(livro);
                }
            }
            
        } catch (SQLiteException e) {
            Log.e(TAG, e.toString());
        }
        finally{
            if (cursor != null) {
                if (!cursor.isClosed()) {
                    cursor.close();
                }
            }
        }        
        return livros;
    }
    
    
    private ContentValues contentLivro(Livro livro){
        ContentValues values = new ContentValues();
        values.put("titulo", livro.getTitulo());
        values.put("autor", livro.getAutor());
        values.put("ano_publicacao", livro.getAnoPublicacao());
        values.put("genero", livro.getGenero());
        return values;
    }
    
    /**
     * Insere um livro.
     * @param livro
     * @return Retorna o id do livro inserido ou -1 se ocorrer
     * erro na inserção do livro.
     */
    public long insertLivro(Livro livro){
        long id = 0;
        
        try {
            ContentValues values = contentLivro(livro);
            id = db.insert(TABLE_NAME, "", values);
            
        } catch (SQLiteException e) {
            Log.e(TAG, e.toString());
        }        
        return id;
    }
    
    /**
     * Exclui um livro.
     * @param titulo Titulo do livro a ser excluído
     * @return
     */
    public boolean excluirLivro(String titulo){
        boolean resultado = false;
        try {
            String where = "titulo=?";
            String[] args = new String[]{titulo};
            
            int num = db.delete(TABLE_NAME, where, args);
            
            // Verifica se o livro foi excluída
            if (num == 1) {
                resultado = true;
            }            
        } catch (SQLiteException e) {
            Log.e(TAG, e.toString());
        }
        
        return resultado;
    }
    
    public boolean alterarLivro(Livro livro){
        boolean resultado = false;
        try {
            
            String where = "_id=?";
            String[] args = new String[]{String.valueOf(livro.getId())};
            
            int num = db.update(TABLE_NAME, contentLivro(livro), where, args);
            
            // Verifica se o livro foi alterado
            if (num == 1) {
                resultado = true;
            }            
        } catch (SQLiteException e) {
            Log.e(TAG, e.toString());
        }
        
        return resultado;
    }    
}


A classe Principal exibe o menu da aplicação em um ListView com os itens Visualizar, Inserir, Alterar,  Excluir. Esta classe é composta pelos métodos:
  • onCreate(Bundle): Inicializa a base de dados e monta o menu.
  • onDestroy(): Fecha a base de dados quando a aplicação é finalizada.
  • onItemClick(AdapterView, View, int, int): Herda da classe ListActivity e trata o evento click do ListView chamando o Intent apropriado de acordo com o item clicado no menu.
public class Principal extends ListActivity implements OnItemClickListener {
    public static LivroDb livros;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // Cria ou abre a base de dados se já existe
        livros = new LivroDb(this);
        String[] menu = new String[] {"Visualizar", "Inserir",
                "Alterar", "Excluir"};
        
        ListView listView = getListView();
        listView.setAdapter(new ArrayAdapter<String>(this, 
                android.R.layout.simple_list_item_1, menu));
        listView.setOnItemClickListener(this);
        
    }
    
    @Override
    protected void onDestroy() {
         super.onDestroy();     
         // Fecha a base de dados
         livros.close();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        Serializable listLivros = (Serializable)livros.selectLivros();
        
        switch (position) {
        case 0: // Visualizar 
            Intent intentVisualizar = new Intent(this, VisualizarActivity.class);
            intentVisualizar.putExtra("livros", listLivros);
            intentVisualizar.putExtra("tipo", "visualizar");
            startActivity(intentVisualizar);
            break;

        case 1: // Inserir
            startActivity(new Intent(this, InsertActivity.class));
            break;
        
        case 2: // Alterar
            Intent intentAlterar = new Intent(this, VisualizarActivity.class);
            intentAlterar.putExtra("livros", listLivros);
            intentAlterar.putExtra("tipo", "alterar");
            startActivity(intentAlterar);
            break;
            
        case 3: // Excluir
            Intent intentExcluir = new Intent(this, VisualizarActivity.class);
            intentExcluir.putExtra("livros", listLivros);
            intentExcluir.putExtra("tipo", "excluir");
            startActivity(intentExcluir);
            break;
            
        default:
            break;
        }
    }
}

visualizar

A classe VisualizarActivity cria a tela de visualização da relação de livros cadastrados na base de dados. Esta tela além de exibir os livros cadastrados na base de dados, também é utilizada para permitir que o usuário selecione um livro para fazer alteração dos dados ou exclua o livro selecionado. Possui os métodos:
  • onCreate(Bundle): Inicializa as variáveis.
  • onResume(): Exibe a relação de livros.
  • onItemClick(AdapterView, View, int, long): Exibe a tela para alterar ou exclui o livro selecionado.
  • onDestroy(): Fecha a base de dados.
public class VisualizarActivity extends ListActivity implements OnItemClickListener {
    private ListView listView;
    private String tipo; // tipo de activity a ser chamada
    private LivroDb livroDb;
    List<Livro> livros;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        livroDb = new LivroDb(this);        
        listView = getListView();
        listView.setOnItemClickListener(this);
    
    }
    
    @SuppressWarnings("unchecked")
    @Override
    protected void onResume() {
        super.onResume();        
        
        String[] titulos = null;
        
        Intent intent = getIntent();
        
        if (intent != null) {
            livros = (ArrayList<Livro>) intent.getSerializableExtra("livros");
            
            titulos = new String[livros.size()];
            int i = 0;
            for (Livro livro : livros) {
                titulos[i] = livro.getTitulo();
                i++;
            }
            
            setListAdapter(new ArrayAdapter<String>(this,
                    android.R.layout.simple_list_item_1, titulos));

            // Define o tipo de Activity a ser chamada
            tipo = intent.getStringExtra("tipo");
            
            if (tipo.equals("alterar")) {
                setTitle("Selecione o livro para alterar");
            }else if (tipo.equals("excluir")) {
                setTitle("Selecione o livro para excluir");
            }
        }
    }
    
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        
        if (tipo.equals("alterar")) {
            
            // Armazena as informações do livro selecionado
            Livro livro = livros.get(position);
            // Chama a tela de Alterar passando as informações do livro
            // como parâmetro
            Intent intent = new Intent(this, AlterarActivity.class);
            intent.putExtra("livro", livro);
            startActivity(intent);
        }
        
        if (tipo.equals("excluir")) {
            String titulo = (String) listView.getItemAtPosition(position);
            boolean excluiuLivro = livroDb.excluirLivro(titulo);
            
            if (excluiuLivro) {
                Toast.makeText(this, "O livro " + titulo + " foi excluído com sucesso",
                        Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this, "O livro " + titulo + " não foi excluído com sucesso",
                        Toast.LENGTH_SHORT).show();
            }
        }
        finish();
    }
        
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (livroDb != null) {
            livroDb.close();
        }
    }

}
visualizar

A classe InsertActivity cria a tela utilizada para inserir o livro. Possui os métodos:
  • onCreate(Bundle): Monta a tela de inserção dos dados do livro.
  • onClick(View): Insere os dados do livro no base de dados. Método chamado quando o botão Inserir é clicado.
  • onDestroy(): Fecha a base de dados.
public class InsertActivity extends Activity implements OnClickListener {
    private EditText editTitulo;
    private EditText editAutor;
    private EditText editAno;
    private EditText editGenero;
    private Button buttonInserir;
    private LivroDb livroDb;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.insere_altera);
        setTitle("Inserir Livro");
        editTitulo = (EditText)findViewById(R.id.editTitulo);
        editAutor = (EditText)findViewById(R.id.editAutor);
        editAno = (EditText)findViewById(R.id.editAno);
        editGenero = (EditText)findViewById(R.id.editGenero);
        buttonInserir = (Button)findViewById(R.id.buttonInserirAlterar);
        buttonInserir.setText("Inserir");
        
        buttonInserir.setOnClickListener(this);
        
    }

    @Override
    public void onClick(View arg0) {
        Livro livro = new Livro();
        livroDb = new LivroDb(this);
        long id = 0;
        
        livro.setTitulo(editTitulo.getText().toString());
        livro.setAutor(editAutor.getText().toString());
        livro.setAnoPublicacao(editAno.getText().toString());
        livro.setGenero(editGenero.getText().toString());
        
        id = livroDb.insertLivro(livro);
        
        if (id != -1) {
            Toast.makeText(this, "O livro foi inserido com sucesso.", Toast.LENGTH_LONG).show();
        }
        
        livroDb.close();
        
        finish();
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (livroDb != null) {
            livroDb.close();
        }
    }
inserir

A classe AlterarActivity altera os dados do livro já cadastrado na base de dados. Possui os métodos:
  • onCreate(Bundle): Monta a tela com os dados do livro cadastrados na base de dados, permitindo que o usuário faça as alterações necessárias e salve na base de dados.
  • onClick(View): Faz a alteração das informações do livro na base de dados.
  • onDestroy(): Fecha a base de dados.
public class AlterarActivity extends Activity implements OnClickListener {
    private EditText editTitulo;
    private EditText editAutor;
    private EditText editAno;
    private EditText editGenero;
    private Button buttonAlterar;
    private LivroDb livroDb;
    private Livro livro;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(R.layout.insere_altera);
        setTitle("Alterar livro");
        editTitulo = (EditText)findViewById(R.id.editTitulo);
        editAutor = (EditText)findViewById(R.id.editAutor);
        editAno = (EditText)findViewById(R.id.editAno);
        editGenero = (EditText)findViewById(R.id.editGenero);
        buttonAlterar = (Button)findViewById(R.id.buttonInserirAlterar);
        buttonAlterar.setText("Alterar");
        buttonAlterar.setOnClickListener(this);
        
        Intent intent = getIntent();
        if (intent != null) {
            livro = (Livro) intent.getSerializableExtra("livro");
            // Exibe as informações do livro selecionado
            editTitulo.setText(livro.getTitulo());
            editAutor.setText(livro.getAutor());
            editAno.setText(livro.getAnoPublicacao());
            editGenero.setText(livro.getGenero());
        }
    }

    @Override
    public void onClick(View v) {
        livroDb = new LivroDb(this);
        boolean resultado = false;
        
        Livro livroAlterado = new Livro();
        // O id do livro com os dados alterados permanece o mesmo
        livroAlterado.setId(livro.getId());
        livroAlterado.setTitulo(editTitulo.getText().toString());
        livroAlterado.setAutor(editAutor.getText().toString());
        livroAlterado.setAnoPublicacao(editAno.getText().toString());
        livroAlterado.setGenero(editGenero.getText().toString());
        
        resultado = livroDb.alterarLivro(livroAlterado);
        
        if (resultado == true) {
            Toast.makeText(this, "O livro foi alterado com sucesso.", Toast.LENGTH_LONG).show();
        }
        
        livroDb.close();
        
        finish();        
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (livroDb != null) {
            livroDb.close();
        }
    }
}

alterar2

O arquivo da base de dados livros, pode ser obtido no diretório data/data/br.com.exemplo.sqlite/database através do emulador do Android no Eclipse.

diretorio

As classes não detalhadas no post bem como o projeto podem ser obtidos aqui
O projeto foi desenvolvido com a API 8 do Android e testado no emulador com Android versão 2.2.

Post Relacionado: