Lista de coleções
Bem, você viu como mapear tipos simples. Agora é hora de passar para questões mais interessantes - como mapear coleções de objetos.
E podemos ter objetos em 5 grupos:
- Array - uma matriz de objetos
- Lista - lista de objetos
- Conjunto - conjunto de objetos
- Mapa - um dicionário de objetos
- Coleção - uma coleção de objetos
E um exemplo de uma classe com um campo de coleção:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@magical-annotation
public List messages;
}
Então, o que é essa anotação mágica que nos permitirá armazenar não um campo, mas muitos valores?
Essa anotação é chamada @ElementCollection . Exemplo:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
public List<String> messages;
}
Está escrito de maneira muito simples, mas funciona de maneira não trivial.
mesa auxiliar
Todos os campos da classe Entity que contêm muitos elementos e são marcados com a anotação @ElementCollection estão contidos no banco de dados em uma tabela auxiliar especial. O que, de fato, é lógico.
Esta tabela pode conter dados em duas formas:
- Ordered (List, Map) contém três colunas:
- Coluna Chave (Chave Estrangeira) – referência ao ID do objeto pai.
- Coluna de índice - posição/índice na coleção.
- Coluna do elemento - valor.
- Unordered (Set) contém duas colunas:
- Coluna Chave (Chave Estrangeira) – referência ao ID do objeto pai.
- Coluna do elemento - valor.
Você também pode definir o nome dessa tabela explicitamente usando uma anotação:
@CollectionTable(name="table_name")
Exemplo:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message")
public List<String> messages;
}
Importante! Se a anotação @CollectionTable não for especificada, o Hibernate criará o próprio nome da tabela com base no nome da classe e no nome do campo: a classe User e o campomensagensnomeie a tabela "User_messages".
coleção coleção
Mas não vamos deixar a criação da tabela auxiliar para o Hibernate e criá-la nós mesmos. Primeiro precisamos criar uma tabela com duas colunas:
CREATE TABLE user_message {
user_id INT,
message VARCHAR(255)
};
Observe que esta tabela não possui sua própria coluna de id. Esta é a principal característica das mesas auxiliares. Você se familiarizará com outros tipos de tabelas auxiliares um pouco mais tarde.
Agora precisamos mapear esta tabela para o nosso campomensagensna classe Usuário . Isso ficará assim:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "message")
public Set<String> messages;
}
Aqui vale a pena prestar atenção a duas coisas.
Primeiro, a coluna da mensagem, especificada com a anotação @Column(name = "message") , está na tabela auxiliar user_message, não na tabela user.
Em segundo lugar, na anotação @JoinColumn(name = "user_id") , especificamos o nome da coluna user_id, que se refere ao id da tabela user. Isso é para que o Hibernate saiba como combiná-los corretamente.
Coleção
Se você deseja armazenar os elementos ordenados de uma lista ou array em uma tabela auxiliar, você precisa de uma tabela com três colunas:
CREATE TABLE user_message {
user_id INT,
index INT,
message VARCHAR(255)
};
Se você não gostar do nome da coluna "index" ou não puder alterá-lo, poderá especificar um nome diferente durante o mapeamento. Para fazer isso, você precisa usar a anotação @Index .
Exemplo:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message",
indexes = { @Index(columnList = "list_index") }
joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "message")
public List<String> messages;
}
Coleção de mapas
E, finalmente, você deseja armazenar não apenas uma coleção, mas um HashMap e precisa de duas colunas em uma tabela auxiliar para isso:
CREATE TABLE user_message {
user_id INT,
key VARCHAR(255),
message VARCHAR(255)
};
Para especificar uma chave para um Mapa, você precisa da anotação @MapKeyColumn .
Exemplo:
@Entity
@Table(name="user")
class User {
@Id
@Column(name="id")
public Integer id;
@ElementCollection
@CollectionTable(name="user_message", joinColumns = @JoinColumn(name = "user_id"))
@MapKeyColumn(name = "key")
@Column(name = "message")
public Map<String, String> messages;
}
Você pode encontrar mais informações na documentação oficial .