Mobile

Databases em Android (ORMLite) – 4

 Android: ORMLite – 2.

 

O gerenciamento de chaves estrangeiras em ORMLite é um pouco diferente do que normalmente é feito em outros frameworks de ORM, como  o Hibernate. Basicamente, são utilizadas as seguintes anotações para este gerenciamento:

  • @ForeignCollectionField – Para coleções estrangeiras.

Obs.: O ORMLite suporta apenas que as coleções sejam: ForeignCollection ou Collection, pois outros tipos são muito “pesados” e com diversas funcionalidades a mais para suportar. Outro detalhe é que, para que o ORMLite consiga identificar os relacionamentos, todos devem ser bi-direcionais, ou seja, Para cada coleção mapeada com ForeignCollectionField, o objeto referenciado deve conter uma referencia a classe que mantém a coleção.

  • @DatabaseField(foreign = true) – Para objetos estrangeiros.

O ORMLite provê algumas funcionalidades interessantes para lidar com objetos e coleções estrangeiras, dentre estas funcionalidades, eu citarei três neste post. Seguem:

  • foreignAutoRefresh – Por padrão, um objeto estrangeiro recuperado pelo framework, traz apenas o seu id. Se quiser ter acesso às propriedades deste objeto, deve-se fazer um refresh no mesmo. Com o seu devido dao, da seguinte forma: “dao.refresh(objeto)”. Com esta propriedade setada como “true” na anotação do objeto estrangeiro, o framework realizará este refresh automaticamente ao recuperar o objeto pai (É o equivalente ao “EAGER” em Hibernate, por exemplo).
  • maxForeignAutoRefreshLevel – Esta propriedade possibilita que seja definida a quantidade de níveis que um “autoRefresh” deve executar, permitindo que o código seja consistente e não possua loops infinitos, quando , por exemplo, dois objetos se referenciam.
  • maxEagerForeignCollectionLevel – Assim como a propriedade anterior, esta também define a profundidade que o framework deve trazer de informações sobre um determinado objeto. Neste caso, esta propriedade é valida para a anotação “ForeignCollectionField”, que trata de relacionamentos ManyToOne

Utilizando as anotações acima fica bastante intuitiva a criação de relacionamentos OneToMany, OneToOne e ManyToOne.

 

Usuario:

[cc lang=”java” width=”100%”]

@DatabaseTable(tableName = “USUARIO”)
public class Usuario {

/** The id. */
@DatabaseField(columnName = “id”, id = true, generatedId = true)
private int id;

/** The login. */
@DatabaseField(columnName = “login”, canBeNull = false)
private String login;

/** The nome. */
@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;

/** The idade. */
@DatabaseField(columnName = “idade”, dataType = DataType.INTEGER,
canBeNull = false)
private int idade;

@DatabaseField(columnName = “setor”, foreign = true)
private Setor setor;

[/cc]

 

Post

[cc lang=”java” width=”100%”]

@DatabaseTable(tableName = “POST”)
public class Post {

/** The id. */
@DatabaseField(columnName = “id”, id = true, generatedId = true)
private Long id;

/** The titulo. */
@DatabaseField(columnName = “titulo”, canBeNull = false)
private String titulo;

/** The conteudo. */
@DatabaseField(columnName = “conteudo”, canBeNull = false)
private String conteudo;

/** The usuario. */
@DatabaseField(canBeNull = false, foreign = true)
private Usuario usuario;

[/cc]

 

Setor

[cc lang=”java” width=”100%”]

@DatabaseTable(tableName = “SETOR”)
public class Setor {

@DatabaseField(id = true, generatedId = true, columnName = “id”)
private Long id;

@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;

@ForeignCollectionField(eager = true)
private Collection usuarios;
// private ForeignCollection;

[/cc]

 

Para a criação de relacionamentos ManyToMany, entretanto, deve ser criada uma outra entidade que gerencie estes relacionamentos, como no código a seguir.

Funcionario

[cc lang=”java” width=”100%”]

@DatabaseTable(tableName = “FUNCIONARIO”)
public class Funcionario {

@DatabaseField(id = true, generatedId = true, columnName = “id”)
private Long id;

@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;

[/cc]

 

Projeto

[cc lang=”java” width=”100%”]

@DatabaseTable(tableName = “PROJETO”)
public class Projeto {

@DatabaseField(id = true, generatedId = true, columnName = “id”)
private Long id;

@DatabaseField(columnName = “nome”, canBeNull = false)
private String nome;

[/cc]

 

ProjetoFuncionario

[cc lang=”java” width=”100%”]

@DatabaseTable(tableName = “PROJETO_FUNCIONARIO”)
public class ProjetoFuncionario {

/** The id. */
@DatabaseField(columnName = “id”, id = true, generatedId = true)
private Long id;

/** The funcionario. */
@DatabaseField(
columnName = “funcionario_id”, canBeNull = false,
uniqueCombo = true)
private Funcionario funcionario;

/** The projeto. */
@DatabaseField(
columnName = “projeto_id”, canBeNull = false, uniqueCombo = true)
private Projeto projeto;

[/cc]

 

Infelizmente a criação de relacionamentos ManyToMany no ORMLite é um pouco precária. É preciso tomar cuidado com o gerenciamento destes relacionamentos e é importante que alguns cuidados sejam tomados, como definir as propriedades canBeNull e uniqueCombo para true, fornecendo um pouco mais de consistência ao código e ao banco.

 

Este foi o quarto post sobre Databases no Android, espero que tenham gostado. Quaisquer dúvidas, sugestões e/ou reclamações, comentem!

 

_________________________________________

Lucas Oliveira – Analista Programador na redspark.
Bacharel em Sistemas de Informação pela Universidade de São Paulo.
@OliveiraLima_

 

5 Comments

  • Donizete disse:

    Muito boa explicação, Simples, clara e direta.

  • Fabio Dresch disse:

    Minha dúvida é quanto a anotação na tabela ProjetoFuncionario:
    os atributos funcionario_id e projeto_id são primary keys também? Pois a tag “foreign = true” não é informada.
    Como o ormlite trata isso?

  • Lucas Oliveira disse:

    Olá Fábio!

    Como eu disse no post, o ORMLite não dá um bom suporte aos relacionamentos ManyToMany. Desta forma, este relacionamento está sendo feito ‘na mão’ (por isso a utilização de um campo ‘id’ na entidade ProjetoFuncionario).

    Para conferir maior consistencia aos dados, utilize as tags “canBeNull = false” e “uniqueCombo = true”. Estas tags garantirão que sempre existam um projeto e um funcionario no relacionamento, e também que sejam únicos. Esta tarefa deveria ser feita pelo framework, mas, infelizmente, ainda não existe este suporte.

    Att,

    Lucas Oliveira – Analista Programador na DClick.
    Bacharel em Sistemas de Informação pela Universidade de São Paulo.
    @OliveiraLima_

  • Fabio Dresch disse:

    Entendido mestre, seria fácil se um ManyToMany fosse da mesma forma que no Hibernate, mas paciencia né ,a tecnologia é nova ainda…

    @ManyToMany(mappedBy = “habilidadeList”)
    private List alunoList;

    @JoinTable(name = “alunohabilidade”, joinColumns = {
    @JoinColumn(name = “PESSOA_ID”,
    referencedColumnName = “PESSOA_ID”)},
    inverseJoinColumns = {
    @JoinColumn(name = “HABILIDADE_ID”,
    referencedColumnName = “HABILIDADE_ID”)})
    @ManyToMany
    private List habilidadeList;

    Att.

  • Denislite disse:

    Gostaria de saber se com anotacoes jpa (http://www.slideshare.net/lucasaquiles/orm-android) o relacionamento many2many fica mais elegante. Faça o teste e post para nós.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Compartilhe isso: