Informações
| Tipo: | Tutorial |
|---|---|
| Data de Publicação: | 18/12/2005 |
| Revisado em: | 18/12/2005 |
Vote!
Tags Relacionadas
Comentários ( 0 )
Imprimir
Mapeando Coleções com Hibernate
por:
Raphaela Galhardo (raphaela@jeebrasil.com.br)
Gleydson Lima (gleydson@jeebrasil.com.br)
Este tutorial apresenta o mapeamento de coleções usando o Hibernate.
Introdução
O mapeamento de coleções já foi apresentado nos tutoriais sobre associações. Essa seção está destinada a apresentar o mapeamento dos quatro tipos de coleções existentes: Set, Bag, List e Map.
Set
Um Set é um conjunto que contém elementos únicos. Como já citado, o seu mapeamento é feito através da tag set e possui o conjunto de atributos mostrado na Listagem 1. Esses atributos são semelhantes para os demais tipos de coleções a serem apresentadas.
<set
name="nomePropriedade”
table="nomeTabela"
schema="nomeEsquema"
lazy="true|false"
inverse="true|false"
cascade="all|delete|save-update|delete|delete-orphan|all-delete-
orphan"
sort="unsorted|natural|comparatorClass"
order-by="nome_coluna asc|desc"
where="condição sql arbitrária">
<key .../>
<element .../> | <one-to-many .../> | <many-to-many .../>
</set>
Listagem 1 - - Coleções: Atributos
Dos atributos ainda não apresentados nos tutoriais sobre associações estão:
- schema: indica o nome do esquema do banco de dados;
- sort: a ordenação pode ser feita na classe Java.
-
- unsorted: desordenada
- natural: odenada a partir do método equals(...);
- comparatorClass: ordenada a partir do método compareTo();
- order-by: ordenação feita no banco de dados a partir do nome da coluna informada. Pode ser ascendente ou descendente;
- where: para informar uma condição arbitrária para a busca da coleção.
- element: indica que a coleção é formada por um tipo primitivo.
Exemplos de Set já foram apresentados nos mapeamentos dos relacionamentos. Para exemplificar o mapeamento de um Set de tipos primitivos considere o mapeamento de uma coleção de String’s para armazenar os telefones de um Aluno, como visto na Figura 1. Então no mapeamento Aluno.hbm.xml deve ser inserido o mapeamento mostrado na Listagem 2.
Figura 1 - Coleção de telefones para Aluno
...
<set name="telefones" lazy="true" table="ALUNO_TELEFONE">
<key column="ID_ALUNO"/>
<element type="java.lang.String"
column="TELEFONE" not-null="true"/>
</set>
...
Listagem 2 - Coleções: Set
Os telefones do aluno são armazenados na tabela ALUNO_TELEFONE. Para o banco de dados está tabela é separada da tabela ALUNO, mas para o Hibernate, ele cria a ilusão de uma única entidade. A tag key indica a chave estrangeira da entidade pai (ID_ALUNO). A tag element indica o tipo da coleção (String) e a coluna na qual está a informação.
Um Set não pode apresentar elementos duplicados, portanto a chave primária de ALUNO_TELEFONE consiste nas colunas ID_ALUNO e TELEFONE.
Dado o mapeamento da coleção de telefones de Aluno, observe o exemplo mostrado na Listagem 3. Neste exemplo, cria-se um objeto Aluno que terá o seu nome definido e um único número de telefone inserido em sua coleção de String’s. Por fim, o objeto Aluno é persistido. O resultado é mostrado na Listagem 4, onde primeiro é inserida uma linha na tabela ALUNO e posteriormente uma linha na tabela ALUNO_TELEFONE.
Aluno aluno = new Aluno();
aluno.setNome("João Maria Costa Neto");
aluno.setTelefones(new HashSet());
aluno.getTelefones().add("32222529");
session.save(aluno);
Listagem 3 - Exemplo de Mapeamento de Set
Hibernate: insert into ALUNO (MATRICULA, NOME, CPF,
ID_CURSO, ID_ALUNO) values (?, ?, ?, ?, ?)
Hibernate: insert into ALUNO_TELEFONE (ID_ALUNO,
TELEFONE) values (?, ?)
Listagem 4 - Resultado da execução do código presente na Listagem 3
List
Um List é uma coleção ordenada que pode conter elementos duplicados. O mapeamento de uma lista requer a inclusão de uma coluna de índice na tabela do banco de dados. A coluna índice define a posição do elemento na coleção, como visto na Figura 2 no mapeamento da coleção de telefones da entidade Aluno como sendo um List. Dessa maneira, o Hibernate pode preservar a ordenação da coleção quando recuperada do banco de dados e for mapeada como um List. Observe o mapeamento da coleção telefones na Listagem 5.
Figura 2 - Coleção de telefones para Aluno: List
...
<list name="telefones" lazy="true" table="ALUNO_TELEFONE">
<key column="ID_ALUNO"/>
<index column="POSICAO"/>
<element type="java.lang.String"
column="TELEFONE" not-null="true"/>
</list >
...
Listagem 5 – Coleções: List
Mapeando a coleção como um List, a chave primária da tabela ALUNO_TELEFONE passa a ser as colunas ID_ALUNO e POSICAO, permitindo a presença de telefones (TELEFONE) duplicados na coleção.
Maps
Maps associam chaves aos valores e não podem conter chaves duplicadas. Eles diferem de Sets no fato de que Maps contêm chaves e valores, ao passo que Sets contêm somente a chave.
O mapeamento de um Map é semelhante ao de um List, onde o índice de posição passa a ser a chave. Veja a Figura 3. A Listagem 6 apresenta a coleção de telefones sendo mapeada como um Map. A chave primária da tabela ALUNO_TELEFONE passa a ser as colunas ID_ALUNO e CHAVE, também permitindo a presença de telefones duplicados na coleção.
Figura 3 - Coleção de telefones para Aluno: Map
...
<map name="telefones" lazy="true" table="ALUNO_TELEFONE">
<key column="ID_ALUNO"/>
<index column="CHAVE" type="java.lang.String"/>
<element type="java.lang.String"
column="TELEFONE" not-null="true"/>
</map>
...
Listagem 6 – Coleções: Map
Bag
Um Bag consiste em uma coleção desordenada que permite elementos duplicados. Em Java não há implementação de um Bag, contudo o Hibernate fornece um mecanismo de que um List em Java simule o comportamento de um Bag. Pela definição de um List, uma lista é uma coleção ordenada, contudo o Hibernate não preserva a ordenação quando um List é persistido com a semântica de um Bag. Para usar o Bag, a coleção de telefones deve ser definida com o tipo List. Um exemplo de mapeamento de um Bag pode ser visto na Figura 4 e Listagem 7.
Figura 4 - Coleção de telefones para Aluno: Bag
Para simular o Bag como List, a chave primária não deve ter associação com a posição do elemento na tabela, assim ao invés da tag index, utiliza-se a tag collection-id, onde uma chave substituta diferente é atribuída a cada linha da tabela na coleção. Entretanto, o Hibernate não fornece nenhum mecanismo para descobrir o valor chave substituta de uma linha em particular.
...
<idbag name="telefones" lazy="true" table="ALUNO_TELEFONE">
<collection-id type="long" column="ID_ALUNO_TELEFONE">
<generator class="sequence"/>
</collection-id>
<key column="ID_ALUNO"/>
<element type="java.lang.String"
column="TELEFONE" not-null="true"/>
</idbag>
...
Listagem 7 - Coleções: Bag
Conclusões
Neste tutorial foram apresentados os mapeamentos de coleções (Bag, Map, List, Set) usando o Hibernate. No próximo tutorial será apresentado o mapeamento de herança utilizando três estratégias distintas: tabela por classe concreta, tabela por hierarquia, tabela por sub-classe. Neste tutorial foram apresentados os mapeamentos de coleções. O próximo tutorial trará o mapeamento de herança, abordando três estratégias distintas.
Referências
- Christian Bauer e Gavin King. Hibernate in Action. 2005.
- Grupo Hibernate. Hibernate Reference Documentation. Version 3.0.5. Obtido em http://www.hibernate.org
- Gleydson de Azevedo Ferreira Lima. Material Didático. 2005.
- Nick Heudecker. Introdução ao Hibernate.
- Maurício Linhares. Introdução ao Hibernate 3.
- Francesc Rosés Albiol. Introducción a Hibernate. 2003.
- Fabiano Kraemer, Jerônimo Jardel Vogt. Hibernate, um Robusto Framework de Persistência Objeto-Relacional. 2005.
