Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Relacionamento entre entidades com o Room

Boa tarde, estou fazendo o curso de android com Room só que fiquei com algumas dúvidas.

No Room, como é feito o seu relacionamento entre entidades ? Com relação as foreign keys, master/detail e tudo mais.

1 resposta
solução!

Fala ai Ueder, tranquilo ?

Não é algo assim tão simples, por isso deixamos fora desse curso e estamos gravando a continuação onde veremos isso.

Bom pensando que temos duas entidades, o Aluno e a Prova. Tecnicamente deveria existir uma terceira entidade que seria a nota ou resultado, que seria para a prova e aluno.

Então teríamos que criar essa entidade:

@Entity
public class Resultado {

}

Agora pensando nos atributos, teríamos algo como a nota, o aluno e a prova, fora o id:

@Entity
public class Resultado {

    @PrimaryKey(autoGenerate = true)
    private Long id;

    private Prova prova;

    private Aluno aluno;

    private Double nota;
}

Isso seria o comum e faltaria apenas a gente falar qual a cardinalidade entre as entidades. Contudo, lembre que o sqlite é bem simples e fazer esse trabalho todo por trás dos panos seria bem custoso, além disse o próprio Room não usa reflection para inferir os tipos e fazer o geramento nesse nível de abstração, por isso temos que deixar nossa entidade exatamente igual com a sua tabela, logo trocaremos os objetos por chaves estrangeiras :

@Entity
public class Resultado {

    @PrimaryKey(autoGenerate = true)
    private Long id;

    private int provaId;

    private int alunoId;

    private Double nota;
}

Agora é necessário avisar ao room que esses valores são chaves estrangeiras, fazemos isso através de um atributo da anotação @Entity chamada foreignKeys onde passamos todas as chaves estrangeiras, como se fosse um array:

@Entity(foreignKeys = {})
public class Resultado {
// restante

Agora é necessário definir cada chave estrangeira, para isso temos um anotação chamada @ForeingKey onde referenciamos tudo sobre a chave, qual é a entidade, como é o nome da coluna onde é a chave estrangeira e qual é o nome da coluna onde é a primary key :

@Entity(foreignKeys = {
    @ForeignKey(entity = Aluno.class, parentColumns = "aluno_id", childColumns = "alunoId"),
        @ForeignKey(entity = Prova.class, parentColumns = "prova_id", childColumns = "provaId")
})
public class Resultado {
// restante

Agora para fazermos a busca trazendo todos os dados, podemos usar o conceito de joins :

    @Query("select * from resultado join prova on prova_id = provaId join aluno on aluno_id = alunoId order by provaId asc ")

Perceba que a entidade resultado, sozinha não consegue representar o resultado dessa busca, para isso podemos criar um objeto que represente o resultado dessa busca :


public class ResultadoComDados {


    public Prova prova;


    public Aluno aluno;


    public Resultado resultado;



}

Nosso método no banco ficaria da seguinte forma :

    @Query("select * from resultado join prova on prova_id = provaId join aluno on aluno_id = alunoId order by provaId asc ")
List<ResultadoComDados> lista();

Se executassemos agora, não teriamos nenhum resultado, isso pois não falamos que esses objetos estão no resultado da query, para isso usamos a anotação @Embedded

public class ResultadoComDados {

    @Embedded
    public Prova prova;

    @Embedded
    public Aluno aluno;

    @Embedded
    public Resultado resultado;

}

Espero que tenha sanado suas dúvidas :D