Uma atividade necessária para o desenvolvimento é a persistência de dados, no Android não é diferente e realizar o Mapeamento Objeto Relacional é bastante trabalhoso. No mundo Java tempos diversas alternativas para como o Hibernate. No Android ainda não temos uma grande solução difundida, mas a o Sugar ORM fornece uma maneira fácil de fazer a persistência.

Primeiro no Gradle importamos a dependência:

compile 'com.github.satyan:sugar:1.4'

Depois basta fazer a configuração que é bastante simples, editamos o arquivo AndroidManifest.xml

<application android:label="@string/app_name" android:icon="@drawable/icon" android:name="info.botecodigital.sugarorm">
.
.
<meta-data android:name="DATABASE" android:value="banco_sugar.db" />
<meta-data android:name="VERSION" android:value="1" />
<meta-data android:name="QUERY_LOG" android:value="true" />
<meta-data android:name="DOMAIN_PACKAGE_NAME" android:value="info.botecodigital.sugarorm.model" />
.
.
</application>
  • DATABASE: o nome do arquivo sqlite gerado. Por exemplo banco.db
  • VERSION: a versão do schema do banco de dados
  • QUERY_LOG: loga as querys gerados
  • DOMAIN_PACKAGE_NAME: Especifica o pacote onde as classes de entidade/dominio estão.

O próximo passo é marcar as classes que serão persistidas, para isso adicionar a anotação @Table e adicionar um atributo private Long id que o Sugar ORM se encarrega de criar a tabela.

@Table
public class Pessoa {
 
    private Long id;
    private String nome;
    private double altura;
    private int idade;
 
    public Pessoa(){
 
    }
 
    public Pessoa(double altura, int idade, String nome) {
        this.altura = altura;
        this.idade = idade;
        this.nome = nome;
    }
 
    /* gets e sets */
}

Se for necessário podemos sinalizar que um campo não deve ser persistido utilizando a anotação @Ignore.

Com a classe de entidade pronta devemos iniciar o contexto do Sugar ORM, isso deve ser feito no método onCreate da activity que iremos querer realizar a persistência.

SugarContext.init( this );

No Android Studio pode ocorrer um erro de criação automática de tabelas, se isso ocorrer basta ir em settings e desabilitar o Instant Run.

Desabilitar Instant Run

Com tudo pronto podemos utilizar os métodos fornecidos pelo Sugar ORM.

Salvar

Pessoa p1= new Pessoa(1.78 , 31 , "Rodrigo"); 
SugarRecord.save(p1);

Buscar Todos

List<Pessoa> pessoas = SugarRecord.listAll( Pessoa.class );

Passamos um objeto class para o método listAll para especificar qual “tabela” estamos buscando.

Buscar por ID

Pessoa p = SugarRecord.findById(Pessoa.class , 1);

Passamos como segundo parâmetro o ID do objeto que estamos tentando recuperar.

Busca com filtro

List<Pessoa> pessoas = SugarRecord.find(Pessoa.class , " idade > ? " , new String[]{"20"} );
 
List<Pessoa> pessoas = SugarRecord.find(Pessoa.class , " nome LIKE ? " , new String[]{"%An%"} );
 
List<Pessoa> pessoas = SugarRecord.find(Pessoa.class , "idade > 18 AND altura > 1.50 "  );

Para utilizarmos filtros passamos uma string que seria o filtro(cláusula WHERE) como segundo parâmetro do método find. Podemos inclusive utilizar parâmetros, colocando “?” nos lugares onde desejamos substituir os valores, e como terceiro parâmetros colocamos um array de Strings onde o primeiro valor dele substituirá o primeiro “?” encontrado na cláusula de filtro, o segundo no segundo e assim por diante.

Também podemos utilizar uma query customizada através do método findWithQuery.

List<Pessoa> pessoas = SugarRecord.findWithQuery(Pessoa.class, "SELECT * FROM Pessoa WHERE nome = ?", "Rodrigo");

Alterando

Pessoa p = SugarRecord.findById(Pessoa.class , 1);
p.setNome("Rodrigo Aramburu");
p.setIdade(32);
 
SugarRecord.save( p );

Deletando

Pessoa p = SugarRecord.findById(Pessoa.class , 1); 
SugarRecord.delete( p );

Query Builder

Em alguns casos precisamos criar uma query mais elaborada e concatenar vários valores pode ficar complicado, então podemos utilizar um builder, com os métodos from para selecionar a tabela, o método where para o filtro, orderBy para ordenação, limit para limitar o número de resultados retornados, e finalmente o método list para efetivamente retornar a coleção List com os dados retornados pela consulta.

List<Pessoa> pessoas = Select.from(Pessoa.class)
                             .where(
                                 Condition.prop("nome").like("%ro%"),
                                 Condition.prop("altura").gt(1.50)
                              )
                              .orderBy("nome")
                              .limit("10")
                              .list();
  • eq(Object): Igual
  • like(Object): LIKE
  • gt(Object): Maior que
  • lt(Object): Menor que
  • isNull(Object): é nulo
  • isNotNull(Object): não é nulo
  • notEq(Object): diferente

Database Migration

Em muitos casos necessitamos alterar uma tabela entre versões do aplicativo, o Sugar ORM fornece um mecanismo para gerenciar estas alterações. Como você deve ter visto mais acima neste post, temos um campo no AndroidManifest.xml que define qual a versão atual do banco, que podemos alterar, e então criar uma pasta sugar_upgrades na pasta assets e dentro dela colocamos os arquivos de script com as alterações(alter table) de uma versão para outra, cada script será nomeado conforme o padrão <versão>.sql. Quando o aplicativo detecta que possui uma versão diferente do banco de dados da aplicação que está atualmente rodando ele irá executar todos os arquivos até atingir a versão do banco atual contida no arquivo AndroidManifest.xml. Por exemplo se no aparelho possui uma versão do aplicativo no qual o banco está na versão 2 e então o app é atualizado para uma versão na qual o banco deve estar na versão 5, ele irá executar automaticamente os scripts: 3.sql, 4.sql e 5.sql.

Bom era isso, espero que facilite o desenvolvimento de vocês como está facilitando o meu 🙂

T++