db mapeamento relacional

72
1 Anderson Gomes da Silva 0205109 8º Semestre Mapeamento Objeto-Relacional Monografia apresentada à disciplina Trabalho de Conclusão do Curso de Ciências da Computação da Faculdade de Jaguariúna, sob. a orientação do Prof. Leonardo Hartleben Reinehr, como exigência parcial para conclusão do curso de graduação. Jaguariúna 2005

Upload: edvaldo-freitas

Post on 21-May-2015

1.641 views

Category:

Education


1 download

DESCRIPTION

Bem, essas são as 4 cláusulas mais utilizadas para fazermos amarrações entre tabelas ou pegarmos valores relacionados.

TRANSCRIPT

Page 1: Db mapeamento relacional

1

Anderson Gomes da Silva

0205109 8º Semestre

Mapeamento Objeto-Relacional

Monografia apresentada à disciplina Trabalho

de Conclusão do Curso de Ciências da

Computação da Faculdade de Jaguariúna, sob.

a orientação do Prof. Leonardo Hartleben Reinehr,

como exigência parcial para conclusão do

curso de graduação.

Jaguariúna

2005

Page 2: Db mapeamento relacional

2

Silva, Anderson Gomes. Estudo Comparativo de Ferramentas de Mapeamento Objeto-Relacional, Monografia defendida e aprovada na FAJ em 15 de Dezembro de 2005 pela banca examinadora constituída pelos professores:

____________________________________________________ Profº. Leonardo Hartleben Reinehr – FAJ - Orientador ____________________________________________________ Profº. Odersom ____________________________________________________ Profº. Roberto Pacheco

Page 3: Db mapeamento relacional

3

Aos meus pais Vital e Maria do Carmo e irmãos Helinton e Erica.

Page 4: Db mapeamento relacional

4

Agradecimentos

Primeiramente à Deus pois sem ele nada é possível; Aos meus pais Vital e Maria do Carmo, por toda educação e amor que foram investidos em mim durante a minha vida; Aos meus irmão e minha namorada que me incentivaram neste trabalho; Aos meus professores, pelas conversas, conselhos e ensinamento que servirão para a vida toda; Ao meu orientador Leonardo Hartleben Reinehr, pela confiança e apoio depositados em mim; À todos meus amigos: Leonardo, Michel, Robson, Juliano, pela amizade e apoio, algo que vai durar muito mais do que quatro anos; À todas as pessoas que me ajudaram nesta etapa da minha vida;

Page 5: Db mapeamento relacional

5

"É muito melhor arriscar coisas grandiosas, alcançar triunfos e glórias, mesmo expondo-se a derrota, do que formar fila com os pobres de espírito que nem gozam muito nem sofrem muito, porque vivem nessa penumbra cinzenta que não conhece vitória nem derrota."

(Theodore Roosevelt)

Page 6: Db mapeamento relacional

6

SILVA, Anderson Gomes. Estudo Comparativo de Ferramentas de Mapeamento Objeto-Relacional. 2005. Monografia. (Bacharelado em Ciências da Computação) – Curso de Ciências da Computação da Faculdade de Jaguariúna, Jaguariúna.

RESUMO

Este trabalho é um estudo comparativo entre as Ferramentas de Mapeamento Objeto-relacional, com enfoque ao Banco de Dados Objeto-Relacional. E tem como objetivo avaliar o estado da arte da teoria de mapeamento objeto-relacional, identificando as características e necessidades desse mecanismo, ele também ira mostrar os principais frameworks para mapeamento objeto-relacional, identificando as vantagens de sua utilização, funcionalidades oferecidas e características de implementação de acordo com a teoria de mapeamento objeto-relacional.

Mostrara também a implementação de um estudo de caso utilizando os frameworks estudados, comparando os resultados obtidos em termos de funcionalidades, performance, flexibilidade e facilidade de uso entre outros aspectos. Palavras-chave: Banco de Dados Relacional, Ferramentas de Mapeamento Objeto-Relacional.

ABSTRACT

This work is a comparative study between the Relational-object Mapping Tools,

with approach to the Database Relational-object. Its target is to evaluate the art state of the theory of mapping relational-object, and identify the characteristics and needs of this mechanism, it will also show the main frameworks to mapping relational-object, to identify the advantages of its use, offered functionalities and implementation characteristics according to the theory of mapping relational-object.

It will also show the implementation of a case-study using the analyzed frameworks, comparing the acquired results in functionalities terms, performance, flexibility and facilities, and others aspects. Key-Word: Relationary data base, Tools of Objeto-Relacional Mapping.

Page 7: Db mapeamento relacional

7

LISTA DE ABREVIATURAS E SIGLAS API Application Programming Interface CASE Computer Aided Software Engineering OID Object Identification OO Orientado a Objeto OO-ER Orientado a Objeto Entidade Relacional UML Unified Modeling Language XMI XML Metadata Interchange

XML eXtensible Markup Language OQL Object Query Language SGBD Sistema Gerenciador de Banco de Dados SGBDOO Sistema Gerenciador de Banco de Dados Orientado a Objeto SGBDOR Sistema Gerenciador de Banco de Dados Objeto Relacional SGBDR Sistema Gerenciador de Banco de Dados Relacionais SQL Structured Query Language ER Entidade Relacionamento

Page 8: Db mapeamento relacional

8

LISTA DE FIGURAS FIGURA 1 Mapeamento Básico FIGURA 2 Mapeamento de Relacionamento (um-para-um) FIGURA 3 Mapeamento de Relacionamento (um-para-muitos)

FIGURA 4 Mapeamento de Relacionamento (muitos-para-muitos) FIGURA 5 Uma Tabela para toda Hierarquia FIGURA 6 Uma Tabela por Classe Concreta FIGURA 7 Uma Tabela por Classe FIGURA 8 Uma Visão Simplista do Hibernate FIGURA 9 Componentes do Hiberante

Page 9: Db mapeamento relacional

9

LISTAS DE TABELAS

TABELA 1 Comparativo entre técnicas de mapeamento de classe TABELA 2 Parâmetros principais para configuração da conexão JDBC TABELA 3 Parâmetros que definem comportamentos em tempo de execução TABELA 4 Criando um SessionFactory através do objeto configuration TABELA 5 Classe candidata a persistência

TABELA 6 Implementação da classe pessoa TABELA 7 Declaração de criação da tabela que armazena a classe pessoa TABELA 8 Mapeando a classe pessoa numa tabela TABELA 9 Tipos de geradores presentes no Hiberante

TABELA 10 Mapeamento da classe pessoa com parâmetros opcionais TABELA 11 Associação entre os tipos do Hibernate, classes Wrapper Java e tipo no BD

TABELA 12 Mapeamento conteplado no SessionFactory TABELA 13 Banco de dados suportados pelo Hibernate TABELA 14 Comparações do Hibernate com outros frameworks de persistências TABELA 15 Diagrama de Classe “Biblioteca Música”

Page 10: Db mapeamento relacional

10

SUMÁRIO

LISTA DE ABREVIATURA E SIGLAS......................................................................7

LISTAS DE FIGURAS..................................................................................................8

LISTAS DE TABELAS.................................................................................................9

1. INTRODUÇÃO………………...............................................................................11

2. REVISÃO BIBLIOGRÁFICA……………………................................................21

3. MAPEAMENTO OBJETO RELACIONAL……………...................................... 39

4. FERRAMENTAS DE MAPEAMENTO OBJETO RELACIONAL………..........59

5. ESTUDO DE CASO…………………...................................................................66

6. RESULTADOS OBTIDOS.....................................................................................68

7. CONCLUSÕES.......................................................................................................70

8. REFERÊNCIA BIBLIOGRÁFICA.........................................................................71

Page 11: Db mapeamento relacional

11

1. INTRODUÇAO Desde seu desenvolvimento até os dias atuais, bancos de dados relacionais sempre

foram os mais utilizados no cenário comercial [DATE, SILBERSCHATZ]. Por outro lado,

nos últimos anos houve uma crescente disseminação das linguagens orientadas a objeto no

desenvolvimento de aplicações. Dessa forma, hoje existe um grande número de aplicações

orientadas a objeto que acessam bancos de dados relacionais.

Existe uma notada incompatibilidade entre o modelo orientado a objetos e o modelo

relacional [AGILE DATA], a qual dificulta a transformação dos dados armazenados em um

modelo para o outro. Por isso, é importante a existência de mecanismos para realizar o

mapeamento das classes do modelo orientado a objeto para tabelas do modelo relacional.

A teoria de mapeamento objeto-relacional define um conjunto de características

necessárias a tais mecanismos, além de apresentar possíveis soluções para os problemas de

incompatibilidade entre os modelos [DATE, SILBERSCHATZ, AGILE DATA].

Os frameworks de mapeamento objeto-relacional oferecem enormes facilidades para

a realização desse tipo de mapeamento, implementando as soluções indicadas na teoria de

mapeamentos e permitindo que as aplicações executem mapeamentos por meio de

configuração e definição de regras ao invés da escrita de linhas de código [Hibernate].

O presente trabalho tem por objetivo mostrar as principais características de um

Mapeamento Objeto-Relacional, com enfoque em um estudo comparativo de ferramentas

de mapeamento e na identificação de problemas e questões em aberto das ferramentas

existentes. Para isso, será implementado um estudo de caso usando diversas tecnologias e

frameworks existentes, comparando os resultados obtidos.

Page 12: Db mapeamento relacional

12

2. REVISÃO BIBLIOGRÁFICA

2.1. BANCO DE DADOS RELACIONAIS

Um banco de dados é um conjunto de informações com uma estrutura regular. Um

banco de dados é normalmente, mas não necessariamente, armazenado em algum formato

de máquina lido pelo computador. Há uma grande variedade de banco de dados, desde

simples tabelas armazenadas em um único arquivo até gigantescos bancos de dados com

muitos milhões de registros, armazenados em salas cheias de dados rígidos. Os banco de

dados caracteristicamente moderno são desenvolvidos desde os anos da década de 1960,

um dos pioneiros neste trabalho foi Charles Bachman. Existe uma grande variedade de

banco de dados, desde exemplos simples como uma simples coleção de tabelas até um

modelo teoricamente definido, o relacional [AGILE DATA].

O modelo de dados lógico relacional é atualmente o mais utilizado nos SGBDs

comerciais. Entretanto, este modelo possui um sistema de tipos simples e restrito, o que

dificulta a descrição de algumas aplicações atuais que necessitam tipos mais complexos e

características do modelo Orientado a Objetos.

Sistemas de Banco de Dados que utilizam o modelo relacional, ou seja, SGBDRs,

são também considerados sistemas de segunda geração de SGBDs visto que os sistemas de

Banco de Dados Hierárquicos e de Rede são considerados a primeira geração. Assim, os

sistemas de Banco de Dados Objeto Relacionais são classificados como a terceira geração

de SGBDs.

2.2. ORIENTAÇÃO A OBJETO

Orientação a objeto pode ser definida como um conjunto de disciplinas de

modelagem de software que facilitam a construção sistemas complexos a partir de

componentes individuais). O apelo intuitivo da orientação a objeto é que ele proporciona

conceitos e ferramentas para modelar e representar o mundo real. As vantagens da

orientação a objeto na programação e na modelagem de dados são muitas[AGILE DATA].

Page 13: Db mapeamento relacional

13

A programação de objeto (orientada) permite uma representação mais direta do

modelo do mundo real no código. O resultado é que a transformação radical das

requisições do sistema (definido em termos de usuários) para especificação do sistema

(definido em termos de computador) é enormemente reduzida.

2.3. IMPEDÂNCIA

Os desenvolvedores de aplicações de bancos de dados (ou seja, qualquer aplicação

que acesse dados armazenados em um banco de dados) freqüentemente se vêem brigando

com problemas de diferenças de impedância: a inerente falta de casamento entre os

modelos de dados relacionais e os orientados a objeto. Os esforços para “mapear” dados

relacionais em um formato utilizável de objetos frequentemente prejudicam tanto a

produtividade do programador quanto o desempenho da aplicação.

A diferença de impedância é uma expressão utilizada em engenharia elétrica, mas

no contexto deste trabalho, refere-se à diferença que existe entre os modelos de dados

relacional e objeto. O modelo relacional organiza todos os dados em linhas e colunas, onde

cada linha representa um registro. Se os dados forem por demais complexos para serem

representados em forma de tabela, tabelas adicionais são cridas para conter as informações

“relacionadas”. Dessa forma, cada tabela em um esquema relacional conterá registro mas

não todos os dados para uma grande quantidade de registros.

O modelo de dados orientado a objeto não está limitado a manter as informações em

linhas e colunas. Em vez disso, o desenvolvedor cria uma definição, um modelo, que

descreve completamente uma determinada classe de informações. Cada registro (objeto) é

uma instância específica daquela classe. Assim, cada registro contém todos os itens de

informação para um, e apenas um, registro. Mas isso não é tudo, as definições de classes

também podem incluir trechos de programação, denominados métodos que apenas sobre os

dados descritos pela classe. Não há uma concepção análoga no modelo relacional.

2.3.1. Usando um banco de dados relacional

Page 14: Db mapeamento relacional

14

Esta seção já discute como a tentativa de usar um banco de dados relacional com

uma aplicação baseada em tecnologia de objetos apresenta sérios problemas de diferença de

impedância. Mas as vezes os desenvolvedores não tem escolha. Pode ser que eles tenham

de acessar dados que residem em um banco de dados relacional. Nesse caso, uma opção é

usar ema ferramenta de “mapeamento objeto-relacional”, quer seja ela autônoma, quer

consiste em facilidades disponível nos bancos de dados “objeto-relacional”.

Essencialmente, as ferramentas de mapeamento criam um arquivo (um mapa) que contém

as regras para a tradução entre objetos e tabelas relacionais. Os desenvolvedores devem

especificar exatamente como a tradução será feita, ou seja, que propriedades do objeto

correspondem a quais colunas de que tabelas e vice-versa. Uma vez criado, o mapa é salvo

e invocado sempre que uma aplicação move os dados para o banco de dados. Algumas

ferramentas de mapeamento objeto relacional provêem um componente de cachê em tempo

de execução para ajudar a compensar a perda de desempenho causada pela tradução entre

as formas relacionais e de objetos.

Além de poder causar problema de performance durante a execução, o mapeamento

objeto-relacional pode atrasar significativamente o desenvolvimento da aplicação. A

maioria das ferramentas de mapeamento não implementa conceitos de modelagem de

objetos, como herança e polimorfismo, ou o faz apenas parcialmente. Assim, à medida que

uma aplicação é adaptada e modificada, mapas objeto-relacional novos e atualizados têm de

ser criados.

Os desenvolvedores que enfrentam o problema da diferença de impedância entre

aplicação orientadas a objeto e bancos de dados relacionais relacional podem querer

considerar a opção de migrar os dados para um sistema de armazenamento mais amigável.

Eles devem então avaliar, o esforço de reformatar e transferir seus dados uma só vez, em

relação ao trabalho constante e as perdas de desempenho que resultam do uso de um mapa

objeto-relacional.

2.3.2. Usando um banco de dados de objeto

À primeira vista, parecia que a diferença de impedância poderia ser totalmente

eliminada armazenando-se os dados em um banco “puramente” de objetos. Isso é

Page 15: Db mapeamento relacional

15

parcialmente verdade. Em geral, para uma aplicação orientada a objeto é fácil interagir com

um banco de dados orientado a objeto. No entanto, neste cenário, a diferença de impedância

ocorre quando se quer executar uma consulta SQL a essa base de dados. A SQL é, de longe

a linguagem de consulta mais amplamente utilizada em todo o mundo, e ela assume que os

dados estão armazenados em tabelas do modelo relacional. Alguns fabricantes de banco de

dados orientados a objeto fornecem o acesso a dados via linguagem de consulta de objeto

(OQL, do inglês Object Query Language), mas essas linguagens não têm aceitação

generalizada.

Para ser compatível com as aplicações comuns de analise de dados e de geração de

relatórios, um banco de dados orientado a objeto deve prover algum mecanismo para

representar os dados como tabelas relacionais.

A solução típica é mais uma vez o mapeamento. Os pontos negativos do mapeamento

(perdas de performance de dados) ainda se aplicam ao caso. O aspecto positivo é que o

mapeamento só precisa ser chamado quando uma consulta SQL é feita á base de dados.

2.4. CAMADA DE PERSISTÊNCIA

Podemos definir persistência de dados como uma forma de manter a existência da

informação mesmo fora da aplicação. Podemos persistir a informação em um banco de

dados, em um arquivo de dados ou qualquer outro meio existente e o fato da informação

existir também fora da aplicação faz com que essas informações possam ser compartilhadas

por outras aplicações.

Para permitir um processo de mapeamento entre sistemas baseados em objetos e bases

de dados relacionais, foram propostas diversas idéias que convergiram para o conceito de

Camada de Persistência.

Conceitualmente, uma Camada de Persistência de Objetos é uma biblioteca que

permite a realização do processo de persistência (isto é, o armazenamento e manutenção do

estado de objetos em algum meio não-volátil, como um banco de dados) de forma

transparente. Graças à independência entre a camada de persistência e o repositório de

dados utilizado, também é possível gerenciar a persistência de um modelo de objetos em

diversos tipos de repositórios, com pouco ou nenhum esforço extra. A utilização deste

Page 16: Db mapeamento relacional

16

conceito permite ao desenvolvedor trabalhar como se estivesse em um sistema

completamente orientado a objetos – utilizando métodos para incluir, alterar e remover

objetos e uma linguagem de consulta para SGBDs Orientados a Objetos – comumente a

linguagem OQL – para realizar consultas que retornam coleções de objetos instanciados.

2.4.1. Vantagens da utilização

As vantagens decorrentes do uso de uma Camada de Persistência no

desenvolvimento de aplicações são evidentes: a sua utilização isola os acessos realizados

diretamente ao banco de dados na aplicação, bem como centraliza os processos de

construção de consultas e operações de manipulação de dados (insert, update e delete) em

uma camada de objetos inacessível ao programador. Este encapsula mento de

responsabilidades garante maior confiabilidade às aplicações e permite que, em alguns

casos, o próprio SGBD ou a estrutura de suas tabelas possam ser modificados, sem trazer

impacto à aplicação nem forçar a revisão e recompilação de códigos.

2.4.2. Requisitos de uma camada de persistência

Segundo Scott Ambler, pesquisador e autor de diversos livros, uma Camada de

Persistência real deve implementar as seguintes características:

• Dar suporte a diversos tipos de mecanismos de persistência: um mecanismo de

persistência pode ser definido como a estrutura que armazenará os dados – seja ela

um SGBD relacional, um arquivo XML ou um SGBD OO, por exemplo. Uma

Camada de Persistência deve suportar a substituição deste mecanismo livremente e

permitir a gravação de estado de objetos em qualquer um destes meios.

• Encapsula mento completo da camada de dados: o usuário do sistema de

persistência de dados deve utilizar-se, no máximo, de mensagens de alto nível como

save ou delete para lidar com a persistência dos objetos, deixando o tratamento

destas mensagens para a camada de persistência em si.

• Ações com multi-objetos: Suportar listas de objetos sendo instanciadas e retornadas

da base de dados deve ser um item comum para qualquer implementação, tendo em

vista a freqüência desta situação.

Page 17: Db mapeamento relacional

17

• Transações: ao utilizar-se da Camada de Persistência, o programador deve ser capaz

de controlar o fluxo da transação – ou ter garantias sobre o mesmo, caso a própria

Camada de Persistência preste este controle.

• Extensibilidade: A Camada de Persistência deve permitir a adição de novas classes

ao esquema e a modificação fácil do mecanismo de persistência.

• Identificadores de Objetos: A implementação de algoritmos de geração de chaves de

identificação garante que a aplicação trabalhará com objetos com identidade única e

sincronizada entre o banco de dados e a aplicação.

• Cursores e Proxies: As implementações de serviços de persistência devem ter

ciência de que, em muitos casos, os objetos armazenados são muito grandes – e

recuperá-los por completo a cada consulta não é uma boa idéia. Técnicas como o

lazy loading (carregamento tardio) utilizam-se dos proxies para garantir

que atributos só serão carregados à medida que forem importantes para o cliente e

do conceito de cursores para manter registro da posição dos objetos no banco de

dados (e em suas tabelas específicas).

• Registros: Apesar da idéia de trabalhar-se apenas com objetos, as camadas de

persistência devem, no geral, dispor de um mecanismo de recuperação de registros -

conjuntos de colunas não encapsuladas na forma de objetos, como resultado de suas

consultas. Isto permite integrar as camadas de persistências a mecanismos de

geração de relatórios que não trabalham com objetos, por exemplo, além de permitir

a recuperação de atributos de diversos objetos relacionados com uma só consulta.

• Arquiteturas Múltiplas: O suporte a ambientes de programas stand-alone, cenários

onde o banco de dados encontra-se em um servidor central e mesmo arquiteturas

mais complexas (em várias camadas) deve ser inerente à Camada de Persistência, já

que a mesma deve visar a reusabilidade e fácil adaptação a arquiteturas distintas.

• Diversas versões de banco de dados e fabricantes: a Camada de Persistência deve

tratar de reconhecer diferenças de recursos, sintaxe e outras minúcias existentes no

acesso aos bancos de dados suportados, isolando isto do usuário do mecanismo e

garantindo portabilidade entre plataformas.

Page 18: Db mapeamento relacional

18

• Múltiplas conexões: Um gerenciamento de conexões (usualmente utilizando-se de

pooling) é uma técnica que garante que vários usuários utilizarão o sistema

simultaneamente sem quedas de performance.

• Queries SQL: Apesar do poder trazido pela abstração em objetos, este mecanismo

não é funcional em cem porcento dos casos. Para os casos extremos, a Camada de

Persistência deve prover um mecanismo de queries que permita o acesso direto aos

dados – ou então algum tipo de linguagem de consulta similar à SQL, de forma a

permitir consultas com um grau de complexidade maior que o comum.

• Controle de Concorrência: Acesso concorrente a dados pode levar a inconsistências.

Para prever e evitar problemas decorrentes do acesso simultâneo, a Camada de

Persistência deve prover algum tipo de mecanismo de controle de acesso. Este

controle geralmente é feito utilizando-se dois níveis – com o travamento

pessimístico (pessimistic locking), as linhas no banco de dados relativas ao objeto

acessado por um usuário são travadas e torna-se inacessíveis a outros usuários até o

mesmo liberar o objeto. No mecanismo otimístico (optimistic locking), toda a

edição é feita em memória, permitindo que outros usuários venham a modificar o

objeto.

2.4.3. Camadas de persistência e linguagens de programação

Diversas implementações de camadas de persistência estão disponíveis

gratuitamente na Internet. Estas bibliotecas muitas vezes tratam da geração dos esquemas

de dados (mapeamentos) automaticamente e podem até mesmo efetuar uma engenharia

reversa – criando hierarquia de classes a partir de um esquema de tabelas em banco de

dados. As Camadas de Persistência que geralmente trabalham com apenas um esquema de

mapeamento de classes para tabelas, diversas estratégias de geração de identificadores,

suporte a quaisquer tipos de relacionamento e geração de código SQL automatizada.

Na linguagem Java, podemos citar algumas destas bibliotecas de persistência:

• Hibernate – uma implementação que permite a persistência transparente de objetos

em bases de dados utilizando JDBC e o mapeamento de classes para XML. Trata-se

de um serviço de persistência e recuperação de objetos, já que, ao contrário dos

Page 19: Db mapeamento relacional

19

frameworks de persistência, não é necessário estender nenhuma classe especial

para que um objeto possa ser armazenado. Projetado para permitir integração com

ambientes J2EE, o Hibernate utiliza reflexão (reflection) para tratar a persistência,

gerando código SQL à medida que for necessário. Atualmente compatível com 11

SGBDs comerciais em sua versão 1.1 (Oracle, DB2, MySQL, PostgreSQL, Sybase,

SAP DB, HypersonicSQL, Microsoft SQL Server, Progress, Mckoi SQL, Pointbase

e Interbase), o Hibernate é distribuído segundo a licença LGPL e suporta uma API

baseada no padrão ODMG 3.0 (o padrão para construção de SGBDs Orientados a

Objetos). Dentre outros recursos interessantes, o Hibernate suporta gerenciamento

remoto utilizando-se a API JMX e é capaz de gerar esquemas de dados (tabelas)

para representar hierarquias de classes.

• Castor – um framework de ligação de dados (databinding), o Castor propõe-se a ser

"a menor distância entre objetos Java, documentos XML, diretórios LDAP e dados

SQL",promovendo mapeamentos entre todas estas estruturas de representação de

objetos. A API do pacote Castor específica para a persistência em bancos de

dados relacionais é a JDO – uma implementação inspirada no padrão Java Data

Objects da Sun. A API provê integração com ambientes J2EE. Atualmente em sua

versão 0.9, o Castor suporta os SGBDs Oracle, Sybase, SQL Server, DB2, Informix,

PostgreSQL, Hypersonic SQL, InstantDB, Interbase, MySQL e SAP DB. A

distribuição segue a licença LGPL.

• Object-Relational Java Bridge (OJB) - um projeto do grupo Apache para prover

uma implementação open-source dos padrões de mapeamento de objetos ODMG e

JDO, o OJB permite que objetos sejam manipulados sem a necessidade de

implementar nenhuma interface em especial ou estender alguma classe específica. A

biblioteca dá suporte a cenários cliente-servidor (aplicações distribuídas) ou

standalone, de forma que é possível utilizar a API OJB para persistência de

objetos. Além disso, a biblioteca possui integração com o sistema de geração de

logs. Em sua versão 0.9, o OJB dá suporte a configuração de esquemas em tempo de

execução, geração de tabelas para mapear uma hierarquia de classes ou classes

relativas a um conjunto de tabelas e implementa uma série de elementos que visam

melhorar a performance da Camada de Persistência. Os SGBDs suportados pela

Page 20: Db mapeamento relacional

20

implementação atual incluem DB2, Hypersonic SQL, Informix, MS-Access, MS-

SQL Server, MySQL, Oracle, PostgreSQL, Sybase e SAP DB. A distribuição é

feita segundo a licença Apache.

• Torque – um framework de persistência desenvolvido como subprojeto do projeto

Apache Turbine, a API trabalha gerando toda a estrutura de banco de dados, classes

e código SQL para acesso aos dados relativos a um esquema pré-configurado. O

esquema é escrito na forma de um arquivo XML, que é interpretado pela

biblioteca utilizando o Ant, uma ferramenta de compilação de código (build tool) do

projeto Apache. A API torque encontra-se em sua versão 3.0 e é distribuída segundo

a licença Apache.

2.5. O QUE SÃO FRAMEWORKS

Um framework OO é uma estrutura de classes inter-relacionadas que constitui uma

implementação inacabada, para um conjunto de aplicações de um domínio, além de ser uma

técnica que faz o reuso do projeto.

O termo framework que inicialmente estava associado ao conceito de bibliotecas de

classes reutilizáveis, mais recentemente, teve seu conceito estendido para qualquer solução

incompleta que pode ser completada através da instanciação, possibilitando a criação de

mais uma aplicação dentro do domínio-alvo do framework (Esta definição tem

similaridades com a do gerador de artefatos).

Atualmente esta técnica tem sido muito apoiada e utilizada pela comunidade de

desenvolvimento de SI. Há uma vasta gama de frameworks disponíveis, tanto na forma de

software livre quanto proprietário, alguns mais restritos, outros mais flexíveis.

É necessário conhecer bem um framework antes de adotá-lo em seu projeto, muitos

ainda são muito imaturos e podem condenar o software a um curto período de sucesso.

Page 21: Db mapeamento relacional

21

3. MAPEAMNTO OBJETO RELACIONAL

O termo Mapeamento Objeto Relacional refere-se a técnica de mapear os registro do

Banco de Dados em objetos e persistir as informações contidas nos objeto em forma de

linhas e colunas.

Como o próprio nome diz, Mapeamento Objeto / Relacional,é responsável por

mapear classes e atributos do modelo orientado a objeto para tabelas e colunas do banco de

dados.

Existem várias formas de fazer esse mapeamento. Alguns frameworks utilizam a

linguagem XML, outros nos obrigam a implementar alguma Interface ou trabalhar com os

Atributos do .NET, mas o objetivo é sempre o mesmo: Permitir que o framework consiga

gerar os comandos SQL dinamicamente.

Uma outra característica deste modelo é a independência do banco de dados.

Devido a geração de comandos dinâmicos, o framework pode analisar qual banco de dados

a aplicação está acessando e gerar os comandos no dialeto específico do banco de dados, ou

seja, é possível mudar o banco de dados da aplicação apenas alterando um arquivo de

configuração.

3.1. Mapeando objetos para tabelas

Para permitir a correta persistência de objetos em um banco de dados relacional,

algum acordo deve ser feito no tocante à forma como os dados serão armazenados. Existem

diversas técnicas que permitem o mapeamento de conjuntos de objetos, cada qual com suas

vantagens e desvantagens sobre as demais. Em geral, uma Camada de Persistência

implementa uma destas técnicas, de forma que o desenvolvedor de software, ao escolher o

mecanismo de persistência com o qual trabalhará, sabe como deve organizar as tabelas em

seu banco de dados para suportar o esquema de objetos desejado. No decorrer deste artigo,

detalhamos como é feito o mapeamento de cada um dos elementos de um objeto: seus

atributos, relacionamentos e classes descendentes (herança).

Page 22: Db mapeamento relacional

22

3.2. Mapeando atributos

Ao transpor-se um objeto para uma tabela relacional, os atributos do mesmo são

mapeados em colunas da tabela. Este processo de mapeamento deve levar em consideração

fatores como a tipagem dos dados (alguns SGBDs podem não suportar tipos binários

longos, por exemplo) e o comprimento máximo dos campos (no caso de números e strings).

Também é importante lembrar que, em diversos casos, atributos de um objeto não devem

ter obrigatoriamente uma coluna em uma tabela que os referencie. Como exemplo,

podemos citar o valor total de um pedido: este dado poderia ser armazenado no objeto para

fins de consulta, mas mantê-lo no banco de dados talvez não seja uma idéia tão

interessante, por tratar-se de um valor que pode ser obtido através de consultas. Além

disso, existem casos onde um atributo pode ser mapeado para diversas colunas (exemplos

incluem endereços completos, nome dividido em 'primeiro nome' e 'sobrenome' no banco

de dados) ou vários atributos podem ser mapeados para uma mesma coluna (prefixo e

número de telefone, por exemplo). As implementações de Camadas de

Persistência provêem, em alguns casos, suporte a este tipo de situação.

3.3. Mapeamento de classes em tabelas

O mapeamento de estruturas de classes em tabelas de uma base de dados relacional

nem sempre é um processo simples: enquanto alguns acham interessante a adoção de

"tabelões" (isto é, tabelas não-normalizadas agrupando dados de diversas entidades) como

repositório para os dados, outros preferem ater-se às regras propostas pelas teorias de

normalização de bancos de dados relacionais. As três técnicas de mapeamento de objetos

mais comumente implementadas (inclusive em Camadas de Persistência) são detalhadas a

seguir. É comum a adoção de uma destas técnicas, mesmo quando nenhum tipo de

mecanismo de persistência automático é adotado no desenvolvimento.

3.4. Mapeamento de uma tabela por hierarquia

Page 23: Db mapeamento relacional

23

Segundo esta estratégia, toda a hierarquia de classes deve ser representada por uma

mesma tabela no banco de dados: uma coluna que identifique o tipo do objeto serve para

identificar a classe do objeto representado por cada linha na tabela, quando nenhum outro

modo de identificação é viável. As desvantagens desta estratégia são evidentes: a ausência

de normalização dos dados fere as regras comuns da teoria de modelagem de dados – além

disso, para hierarquias de classes com muitas especializações, a proliferação de campos

com valores nulos na maioria das linhas da tabela se torna também um problema potencial.

3.5. Mapeamento de uma tabela por classe concreta

Nesta estratégia, teremos uma tabela no banco de dados para cada classe concreta

presente em nosso sistema. A tabela identifica a classe de todos os elementos contidos na

mesma, tornando desnecessário o mecanismo de Object Type adotado na estratégia

anterior. A estratégia de geração de uma tabela para cada classe concreta leva

à redundância de dados: quaisquer atributos definidos em uma superclasse abstrata na

hierarquia devem ser criados em todas as tabelas que representam subclasses da mesma.

Além disso, mudar o tipo (especializar ou generalizar) um objeto torna-se um problema, já

que é necessário transferir todos os seus dados de uma tabela para outra no ato

da atualização.

3.6. Mapeamento de uma tabela por classe

Na terceira estratégia proposta, criamos uma tabela para cada classe da hierarquia,

relacionadas através do mecanismo de especialização padrão do banco de dados (utilização

de chaves estrangeiras). Segundo esta modalidade de mapeamento, tenta-se ao máximo

manter a normalização de dados, de forma que a estrutura final das tabelas fica bastante

parecida com a hierarquia das classes representada pela UML. A colocação de um

identificador de tipo (Object Type) na classe-pai da hierarquia permite identificar o tipo de

um objeto armazenado nas tabelas do sistema sem forçar junções entre as tabelas,

garantindo melhorias na performance, e é uma estratégia comumente utilizada. Esta é a

técnica que mais naturalmente mapeia objetos para bancos de dados relacionais, de forma

Page 24: Db mapeamento relacional

24

que as Camadas de Persistência geralmente forçam a utilização de um esquema de dados

que siga esta modalidade de mapeamento. A quantidade de junções (joins) entre tabelas

para obter todos os dados de um objeto o seu principal ponto negativo.

A tabela 1 faz um comparativo destas três técnicas quanto à facilidade de consulta a

dados interativa (ad-hoc reporting), facilidade implementação, facilidade de acesso aos

dados, acoplamento dos dados das classes mapeadas, velocidade de acesso e suporte a

polimorfismo.

Uma tabela por hierarquia de classes

Uma tabela por classe concreta

Uma tabela por classe

Ad-hoc reporting Simples Médio Médio/Difícil

Facilidade de implementação

Simples Médio Difícil

Facilidade de acesso Simples Simples Médio/Simples

Acoplamento Muito alto Alto Baixo

Velocidade de acesso Rápido Rápido Médio/Rápido

Suporte a polimorfismos

Médio Baixo Alto

Tabela 1. Comparativo entre técnicas de mapeamento de classes

3.7. Mapeamento de relacionamentos

Os relacionamentos de associação entre objetos são uma das características mais

facilmente mapeadas. Conceitualmente, existem apenas trás tipos de relacionamentos

possíveis (um-para-um, um-para-muitos e muitos-para-muitos).

Relacionamentos um-para-um necessitam que uma chave (foreign key) seja posta

em uma das duas tabelas, relacionando o elemento associado na outra tabela. Dependendo

da disposição desta chave estrangeira, podemos definir a navegabilidade do relacionamento

(que se dá sempre da tabela que possui a chave estrangeira para a tabela referenciada). Para

manter relacionamentos um-para-muitos, adota-se a mesma técnica: uma referência na

forma de chave estrangeira deve ser posta na tabela que contém os objetos múltiplos (lado

Page 25: Db mapeamento relacional

25

"n" do relacionamento).No caso de relacionamentos muitos-para-muitos (ou n-para-n),

convenciona-se criar uma tabela intermediária que armazene pares de chaves, identificando

os dois lados do relacionamento.

Há uma tendência para a utilização de Linguagens de Programação Orientadas a

Objeto(LPOO) e mecanismos de persistência diversos, principalmente, Banco de Dados

Relacionais(BDR).Surge então um problema, a integração entre a linguagem e o BD.

Embora existam várias APIs e modelos de mapeamento que possibilitam esta integração,

elas devem ser utilizadas de acordo com diretrizes para que não se perca os benefícios da

orientação a objetos e nem do BDR.

O simples mapeamento das classes, em nível de projeto, para tabelas do BDR não

garante a resolução do problema, na verdade existem outros aspectos, não menos

importantes, que podem levar a, violação dos princípios básicos da orientação a objetos

como encapsula-mento e modularização, ou descaracterização da arquitetura adotada.

Mesmo assim o modelo de objetos do banco é diferente do modelo de objetos utilizado pela

linguagem de programação. Enquanto a linguagem trabalha com objetos na memória, o

banco trabalha com objetos em disco, o que exige algoritmos e estratégias diferenciadas.

Além de que, os BDOOs não são, atualmente, a tecnologia padrão no mercado, por conta

do legado em investimento em sistemas desenvolvidos, pela cultura dos profissionais

atuando no mercado ou até mesmo por questões de performance.

Algumas ferramentas RAD, como DelphiTM, JbuilderTM e Dreamweaver, tornam

semi-automática a integração de uma LPOO com um BDR. No entanto essa implementação

é realizada sem a preocupação de critérios que garantam a continuidade e reversibilidade da

implementação em relação ao projeto. Estes erros não são somente cometidos nestas

condições, existem diversas “implementações ad hoc” que infringem estes e outros

aspectos.

Um mecanismo de persistência tem três componentes básicos, são eles:

– Regras de mapeamento;

– API de acesso ao Banco de Dados;

– Linguagem de consulta;

Page 26: Db mapeamento relacional

26

Este componentes se interligam para gerar o mecanismo de persistência, que deve

ter como objetivos a maior abstração possível do BDR nas regras de negócio e a melhor

performance possível. Além disso um mecanismo deve considerar também as

funcionalidades tanto da LPOO quanto do BDR, resultando maior reusabilidade,

extensibilidade e eficiência.

No caso de se obter reusabilidade nas regras de negócio orientado a objeto é preciso

seguir o princípio da independência dos objetos de negócio em relação ao mecanismo de

persistência.

As regras de mapeamento gerenciam como o modelo OO que é mais rico

semanticamente, vai ser mapeado para o modelo relacional. Como irão se comportar

herança, agregação, entre outros devem estar definidos nestas regras.

A linguagem de consulta é responsável para manipular os dados do banco, pode ser

baseada em objetos ou não.

As APIs são responsáveis pela integração do mecanismo com as regras de negócio.

Estas podem ser intrusivas ou não. Quando estas impõem regras sob criação das classes

persistentes, a API é intrusiva, caso contrário não.

A tendência é que as APIs sejam não intrusivas, porém dificilmente o BD será

utilizado com eficiência, bem como os conceitos transparentes ao Banco de Dados, como

transações, serão mais difíceis de implementar sem modificar ou denegrir responsabilidades

no modelo de objetos.

Em termos de performance deve-se desenvolver uma política sobre como e quais os

atributos serão carregados, em uma consulta. Podemos utilizar o carregamento antecipado,

ou o carregamento tardio4. Em alguns casos deve-se ter uma política de escrita no BD

também.

3.2. MAPEAMENTO OO – ER

A integração objeto-relacional requer uma estratégia para mapeamento de modelo

objeto para o modelo relacional. O banco de dados relacional possui características

importantes tais como consultas rápidas, compartilhamento de informações entre programas

e armazenamento permanente. O modelo objeto possui componentes, estado e é baseado

Page 27: Db mapeamento relacional

27

em estruturas que combinam código e dados e ainda possuem sua própria identidade

(Object Identification – OID) Esta identidade não depende dos valores que o objeto possui,

ela possibilita estabelecer referências entre objetos e definir os relacionamentos, os quais

podem ser dos seguintes tipos: associação, agregação, generalização/especialização.

OIDs possibilitam simplificar a estratégia de uso de chaves no banco de dados, eles

facilitam a navegação entre objetos simplificados os joins. Outra vantagem é que o uso de

OIDs facilitam a manutenção dos relacionamentos entre objetos. Quando todas as tabelas

possuem suas chaves baseadas num mesmo tipo de colunas, torna-se mais fácil escrever o

código e tirar vantagens disso.

O modelo objeto e o modelo relacional são fundamentalmente diferentes, o modelo

objeto é útil para expressar relações complexas entre objetos nas Linguagens de

Programação Orientada a Objeto como, C++ e Java. Já o modelo relacional é útil para

gerenciar grande volume de dados em Banco de Dados Relacional como, SQL Server e

Oracle.

Sendo assim cada uma das classes do modelo OO é transformada em uma tabela no

modelo relacional. Para as associações, o mapeamento é feito ou com a criação de novas

tabelas ou com a cópia das chaves de uma tabela para outra. Para agregação, a regra é

generalização /especialização, cuja transformação para o modelo relacional é executado

com interação do usuário, uma vez que para um mesmo caso pode haver diferentes formas

de transformação.

Existem algumas regras de transformação que tem por finalidade a conversão do modelo

OO para o modelo relacional. As regras se dividem em (OBJECTMATTER, 2003):

- Mapeamento Básico

- Mapeamento Herança de Classe

- Mapeamento Relacionamento de Objeto

Serão descritas as técnicas fundamentais requeridas para o sucesso do mapeamento

objeto para o relacional. Isto poderá ajudar a rever os conteúdos que predominam no

desenvolvimento e praticas que envolvem este assunto

3.2.1. Mapeamento Básico

Page 28: Db mapeamento relacional

28

A classe pode ser mapeada para tabelas. O simples mapeamento entre a classe

persiste e a tabela é um-para-um. Neste caso, todos os atributos da classe persistente são

representados por todas as colunas da tabela. Cada instância da classe do negócio é

armazenada em uma linha da tabela.

Um atributo de uma classe pode ser mapeado para zero ou mais colunas. È

importante lembrar que nem todos os atributos são persistentes, por exemplo, um atributo

total que é usado para instanciar um somatório, logo, este não é persistido no banco de

dados. Alguns atributos dos objetos são objetos por si só, como exemplo: endereço, cep,

rua,etc.. portanto devem ser tratados como relacionamentos.

3.2.2. Mapeamento herança de classe

O conceito de herança lança vários interesses do entrelaçamento de salvar objetos

em banco de dados relacionais. Este assunto basicamente concentra-se em imaginar como

organizar o atributo herdado em seu modelo persistente. A maneira como será resolvido

este desafio poderá ter um grande impacto no projeto de seu sistema.

Existem três tipos de soluções que são fundamentais para mapear a herança para o modelo

relacional:

- Mapeamento uma tabela para toda hierarquia: com este método mapeia-se toda a

classe de herança para uma tabela, onde todos os atributos de toda a classe da hierarquia

são armazenados e, uma coluna OID é introduzida como chave primária na tabela;

- Mapeando uma tabela por classe: com este método cada tabela inclui tanto os seus

atributos quanto os atributos herdados. Somente as classes “folhas” das hierarquias são

mapeadas para tabelas;

-Mapeando uma tabela por classe; com este método cria-se uma tabela por classe. A

principal vantagem é que esta abordagem é a que esta mais conforme a orientação a

objetos. Os registros estão armazenados nas tabelas apropriadas, de acordo com seus

Page 29: Db mapeamento relacional

29

papeis. Uma desvantagem, neste método são mais tabelas BD (mais tabelas para manter os

relacionamentos).

3.2.3. Mapeando relacionamento de objetos

Não somente devemos mapear os objetos para o banco de dados, mas também

mapear os relacionamentos que envolvem os objetos. Existem quatro tipos de

relacionamento os quais os objetos podem estar envolvidos: generalização, associação,

agregação e composição. Para mapear efetivamente esses relacionamentos, devemos

estender as diferenças entre eles, como implementar a generalização, e como implementar

relacionamento muitos-para-muitos especificamente.

Para o banco de dados, perspectivamente, somente tem diferença entre os

relacionamentos de associação e agregação/composição e como o objeto é firmemente

amarrado a ele. Com a agregação e composição qualquer coisa que você faça com o todo

no banco de dados você sempre precisará fazer nas partes, enquanto que com associação

este não é o caso.

O diagrama de classes é a estrutura das tabelas que são usadas para discutir as varias

Maneiras de relacionamentos de objetos um-para-um, um-para-muitos, muitos-para-

muitos, que podem ser mapeados para o modelo relacional.

No modelo relacional o relacionamento um-para-um, mantém-se, comumente, por

meios de colunas de chaves estrangeiras. Esta coluna de chave estrangeira mantém o valor

da chave primária (OID do objeto) da coluna (objeto) referenciada. O relacionamento um-

para-um pode ser definido como referencia ao atributo, isto pode ser feito

transparentemente convertendo a chave estrangeira do objeto referenciado. Isto também

possibilita a definição do relacionamento um-para-um no modelo relacional usando uma

join table.

No modelo objetos existem dois tipos de relacionamento um-para-muitos:

agregação (parte de), e associação. Um relacionamento de agregação é definido por meios

do próprio atributo e um relacionamento de associação por meios de uma coleção

referenciada ao atributo. A diferença entre as duas é que no relacionamento próprio, que é

próprio é atualizado no banco de dados. Todos os objetos, em todas as suas coleções, são

Page 30: Db mapeamento relacional

30

automaticamente atualizados (este comportamento pode ser modificado em tempo de

execução se necessário).

No modelo relacional, um-para-muitos pode ser definidos usando a coluna de chave

estrangeira ou usando uma join table é uma tabela com o propósito de armazenar os valores

mapeados entre a chave estrangeira das duas tabelas envolvidas no relacionamento.

Um relacionamento muitos-para-muitos pode ser como uma bi-direcional

associação um-para-muitos. Para criar este tipo de relacionamento, simplesmente,

definimos o atributo referenciado na coleção, em cada classe envolvida no relacionamento.

No modelo relacional um relacionamento muitos-para-mutos pode ser definido usando

colunas de chaves estrangeiras ou uma join table.

Para usar chaves estrangeiras, uma coluna com a chave estrangeira é definida para

cada tabela envolvida no relacionamento. Cada coluna da chave estrangeira mantém a

chave da outra tabela. Existem vários tipos que podem ser implementados para associação

muitos-para-muitos usando join table.

Uma das maneiras de implementar relacionamento muitos-para-muitos é usando

uma tabela associativa. O nome da tabela associativa é geralmente a combinação dos nomes

das tabelas que estão associadas ou o nome da associação implementada entre elas. A

associação original possui um relacionamento muitos-para-muitos e com a utilização da

tabela associativa se faz um cruzamento das multiplicações e não se perde essa associação.

O propósito de uma tabela associativa é implementar uma associação descrita em uma

classe associativa.

3.3. OBJETIVOS GERAIS DOS COMPONENTES MAPEAMENTO OO- ER

Mapeamento objeto-relacional é a transformação das regras do modelo objeto para

as regras e normalizações do modelo relacional. Isto significa que existem dois modelos

utilizados na construção de sistemas. O modelo objeto é utilizado para descrever e

apresentar as regras de negócio, enquanto. A utilização do paradigma relacional na

persistência dos objetos, atividade importante para definir a base de dados de sistemas que

utilizam o paradigma orientado a objeto no seu desenvolvimento.

Page 31: Db mapeamento relacional

31

A transformação de uma classe em uma tabela e seus respectivos relacionamentos e

atributos em chaves primárias e chaves estrangeiras define, com mais precisão, questões

relacionadas à performance no acesso aos dados (não fazer um-para-um). O relacionamento

um-para-um, possui algumas desvantagens:

1º são mais tabelas no Banco de Dados (mais tabelas para manter os relacionamentos);

2º o tempo de leitura e escrita de dados será maior usando esta técnica porque varias tabelas

serão acessadas. Neste caso, ceve existir a preocupação em atualizar e manipular as classes

de nível superior na hierarquias profundas, são requeridos múltiplos joins para recuperar as

informações básicas do objeto.

Resumindo, o mapeamento OO-ER é importante para que dois mundos

consolidados (OO – desenvolvimento e ER – base de dados) possam convergir em uma

única solução.

O objetivo principal do componente é fazer o mapeamento objeto-relacional

utilizando como entrada um arquivo XMI que é o padrão entre intercambio de dados

utilizado hoje, e gerando como saída um arquivo .sql para utilização no banco de dados.

3.3.1. Mapeamento básico

Cada classe do modelo será transformada em uma tabela do modelo relacional e,

todos os seus atributos, serão representados por todas as colunas da tabelas. A Figura 1

apresenta um exemplo de mapeamento básico.

A chave primária é definida através da utilização de Object Identification (OID).

Page 32: Db mapeamento relacional

32

FIGURA 1 – Mapeamento Básico

Geração das Primary Keys (OID): Toda a classe transformada m tabela tem um

identificador próprio: o seu OID. O qual facilita o relacionamento entre as tabelas, e com

isso, as consultas na maioria dos casos se tornam mais eficientes.

3.3.2. Mapeamento de relacionamentos

• Um-para-um

- O mapeamento de relacionamentos um-para-um foi implementado no componente

utilizando a chave primária da tabela relacionada como chave estrangeira. A figura

2 apresenta um exemplo de mapeamento um-para-um.

- Coloca-se a chave primaria de uma tabela como chave estrangeira na outra tabela,

independentemente do lado do relacionamento.

FIGURA 2 – Mapeamento de relacionamentos (um-para-um)

• Um-para-muitos

Page 33: Db mapeamento relacional

33

- O mapeamento de relacionamentos um-para-muitos foi implementado no

componente utilizando a chave primária da tabela relacionada como chave

estrangeira da tabela referenciada. A figura 3 apresenta um exemplo de mapeamento

um-para-muitos.

- Coloca-se a chave primária de uma tabela como chave na outra tabela, no lado do

muitos no relacionamento.

FIGURA 3 – Mapeamento de relacionamentos (um-para-muitos)

• Muitos-para-muitos

- O mapeamento de relacionamento muitos-para-muitos foi implementado no

componente utilizando uma tabela associativa. A figura 4 apresenta um exemplo de

mapeamento muitos-para-muitos.

- Cria-se uma terceira tabela que possui as chaves primárias das duas tabelas

relacionadas, como chaves estrangeiras na tabela associativa. O nome da nova

tabela é a junção dos nomes das tabelas relacionadas.

Page 34: Db mapeamento relacional

34

FIGURA 4 – Mapeamento de relacionamentos (muitos-para-muitos)

3.3.3. Generalização

A generalização pode ser mapeada de três formas: uma tabela para toda hierarquia,

uma tabela por classe concreta e uma tabela por classe. O componente contempla as três

formas de mapeamento. Previamente pode-se definir um mapeamento padrão para a

generalização (uso do properties) ou através da escolha, pelo usuário, em tempo de

execução. As três formas são:

• Uma tabela para toda hierarquia: a tabela pai herda os atributos das tabelas filhas, e

permanece o nome da tabela pai, conforme apresenta a figura 5;

Page 35: Db mapeamento relacional

35

FIGURA 5 – Uma tabela para toda hierarquia

• Uma tabela por classe concreta: as tabelas filhas herdam os atributos da tabela pai e

permanecem com os seus nomes. A tabela pai é excluída, conforme apresentado na

figura 6;

FIGURA 6 – Uma tabela por classe concreta

• Uma tabela por classe: para cada classe se gera uma tabela com os seus respectivos

atributos, transformados em colunas e, a herança é representada com um

relacionamento um-para-um entre o pai e seus filhos. Conforme apresentado na

figura 7.

Page 36: Db mapeamento relacional

36

FIGURA 7 – Uma tabela por classe

Page 37: Db mapeamento relacional

37

3.4. REPRESENTAÇÃO DE UM ESQUEMA RELACIONAL

Para que possamos aplicar as regras de mapeamento, consideramos que as relações

no esquema relacional de origem estão no mínimo na 2ª forma normal, ou seja, as relações

podem conter dependência funcionais transitivas, mas não dependências parciais.

Consideramos também que, são conhecidas as chaves primárias e estrangeiras das relações

que compõe o esquema relacional de origem.

Em relação ao particionamento horizontal de tabelas, consideramos que se tal

particionamento existe no esquema relacional de origem, isto foi feito devido á decisão de

projeto. Por não conhecemos o motivo de tal decisão, estabelecemos que: se duas tabelas A

e B são equivalentes, mas são tratadas como tabelas diferentes devido ao particionamento

horizontal, então estas tabelas continuando sendo tratadas como distintas no esquema

objeto-relacional, observamos que, não estamos considerando o problema de performance

durante o mapeamento, uma vez que a tecnologia objeto-relacional ainda é recente, e não se

pode afirmar, deste ponto de vista, qual a melhor estrutura para modelar os dados, diante

das diversas possibilidades oferecidas. Entretanto, procuramos fazer o mapeamento

oferecendo uma melhor modelagem do ponto de vista de compreensão do esquema.

Ainda com o objetivo de minimizar as “falhas” de projeto no esquema relacional de

entrada, definimos, a seguir, um procedimento de pré-processamento deste esquema,

descrito por;

1. Sejam as relações R1 e R2. Se a chave primária de R1 é também uma chave estrangeira

que referencia a chave primária de R2 e a chave primária de R2 é também uma chave

estrangeira que referencia a chave primária de R1, então dizemos que as relações R1 e R2

estão particionadas verticalmente. Neste caso, consideramos que as relações R1 e R2

representam uma única relação (R3), cujos atributos dão dados pela união dos atributos de

R1 e R2. A chave primária de R3 é a mesma de R1 ( que é a mesma chave primária de R2).

Consideramos também, que todas as restrições definidas sobre R1 e R2, tornam-se

Page 38: Db mapeamento relacional

38

restrições sobre R3, exceto as restrições de chave estrangeira de R1 para R2 e vice-versa. A

relação R3 é então definida: R3 (A, B, C, D, E).

A opção de “unir” tabelas particionadas verticalmente deve-se ao seguinte fato: se,

aplicando as regras de mapeamento tais tabelas fossem mapeadas em tabelas de objetos

distintas, que possuem em identificadores únicos. Desta forma, mesmo que dois objetos

possuem a mesma chave-primária, mas em tabelas distintas, então estes objetos possuem

OIds diferentes.

Conforme definido anteriormente, consideramos que as relações do esquema

relacional de entrada podem estar na 2ª forma normal. Desta forma, utilizamos o processo

descrito para relações, de tal forma que se na 3ª forma normal.

3.4.1. Algumas regras para mapeamento

As regras listadas a seguir, para mapear um esquema relacional em objeto-

relacional, são baseadas em um conjunto trabalho, com algumas adaptações para adequar o

modelo objeto-relacional descrito. A maioria destes trabalhos tratam do mapeamento para

estruturas orientadas a objetos.

Regra T1: Toda tabela em um esquema relacional que tem somente um atributo na chave

primária correspondente a uma tabela de objeto-relacional. Os atributos da tabela relacional

tornam-se atributos do tipo de dados estruturados que definem a tabela de objetos.

Regra T2: Se a chave primária de uma tabela no esquema relacional tem mais que um

atributo, e além disso, a tabela possua outros atributos que não pertençam à chave primária,

então esta tabela relacional corresponde a uma tabela de objetos no esquema objeto-

relacional. Os atributos de chave primária que representam chaves estrangeiras, devem ser

mapeados como uma referência ao tipo que define a estrutura de tabelas referenciada pela

chave estrangeira.

Page 39: Db mapeamento relacional

39

Regra T3: Toda tabela em um esquema relacional, cuja chave primária é composta por mais

de um atributo, e todos eles representam chaves estrangeiras. Esta associação é

representada no esquema objeto-relacional através de tabelas aninhadas.

Regra T4: Toda tabela que possui atributos de chave estrangeira que não fazem parte da

chave-primária, estabelece uma associação entre esta tabela e a cada tabela referenciada por

chaves estrangeiras. Esta associação é representada no esquema objeto-relacional através de

referências (tipo de dados ref.).

Regra T5: Todo par de tabelas R1 e R2 que têm as mesmas chaves primárias podem ser

envolvidos em um relacionamento de herança. O relacionamento R1 “ é um “ R2 existe se a

chave primária de R1 é também a chave estrangeira que refere a tabela R2.

Regra T6: Quando um relacionamento de herança esta embutido em uma única tabela , é

necessário extrair regras do banco de dados de uma maneira não convencional. Existem

vários algoritmos que podem identificar tais regras, denominadas “strong rules” em banco

de dados relacionais. Usando-se algum deste algoritmo, pode-se identificar as condições

que são estabelecidas para que um atributo, ou conjunto de atributos, possua valor nulo.

Identificadas estas regras, podem-se extrair da tabela os relacionamentos de herança nela

embutidos. Utilizamos o algoritmo descrito para determinar relacionamento de herança, em

um esquema relacional.

Regra T7: Seja R uma tabela cuja chave primária tem mais que um atributo e no mínimo

um deles não é chave estrangeira, e além disso, R não possui outros atributos que não

pertençam à chave primária. Deve-se então acrescentar um atributo na tabela referenciada

pela chave primária, cujo domínio é um tipo coleção formado pelos atributos de tabelas,

exceto o atributo de chave estrangeira.

Page 40: Db mapeamento relacional

40

4. FERRAMENTAS DE MAPEAMENTO OBJETO RELACIONAL

4.1. FUNCIONALIDADES ESSENCIAIS DE UMA FERRAMENTA DE

MAPEAMENTO OBJETO/RELACIONAL

Já existem hoje no mercado algumas ferramentas capazes de realizar mapeamento

entre objeto e registros de tabelas de banco de dados relacionais, fazendo com que

operações básicas de cadastro como armazenamento, atualizações, exclusão e consultas

possam ser realizadas naturalmente sobre objeto e reflitam por fim em SQL que serão

interpretados pelos bancos relacionais.

Produtos que realizam mapeamento objeto – relacional integram as capacidades das

linguagens de programação orientadas a objeto com sistemas de gerenciamento de bancos

relacionais, como Oracle, DB2, Sysbase, e outros. Produtos que realizam mapeamento

objeto-relacional são projetados para funcionar bem como linguagens de programação

orientadas a objetos.

A definição de correspondência entre elementos modelados em objeto e elementos

no modelo relacional precisa ser de fáceis configurações. Um grande numero de soluções

usa arquivos de configurações XML. Um editor gráfico para edição destes arquivos

consiste em uma vantagem extra e terá melhor preferência pela equipe projetista de

software para momento de realizar-se uma integração da ferramenta ao ambiente de

desenvolvimento.

Ferramentas de mapeamento podem ser mais ou menos genéricas e sua capacidade

de adaptar-se aos recursos existentes é um importante motivo de escolha. Buscar

informações armazenadas em banco de dados relacionais pode prover muita complexidade

se a ferramenta de mapeamento por em uso controle de restrições de integridade sobre o

modelo relacional usado.

A ferramenta deve prover funcionalidade de pesquisa, de montagem de objeto e de

atualizações. Estes mecanismos precisam gerenciar corretamente quaisquer problemas de

transações e adaptar-se a arquitetura do sistema de informações ao qual se destina, mesmo

que seja usado um servidor de aplicação.

Page 41: Db mapeamento relacional

41

A descrição dos tipos de dados varia de um modelo para o outro. A ferramenta de

mapeamento deve estar apta a diferenciar os tipos de dados e propor correspondência no

modelo relacional do banco de dados utilizados.

A partir do momento em que uma empresa desenvolvedora de software opta por uma

ferramenta de mapeamento objeto/relacional ela geralmente tem como objetivo conseguir

as seguintes vantagens no seu processo de engenharia de software:

• Melhorar a manutenibilidade de código. O código relacionado a persistência esta

embutido em um modulo especifico e não é modificado durante os vários ciclos de

vida do desenvolvimento;

• O tamanho de código médio seja reduzido uma vez que o código relacionado a

persistência é inteiramente genérico e não esteja distribuído por toda a aplicação

• O trabalho do(a) desenvolvedor(a) seja facilitado e reduzido, uma vez que ele não

tenha mais que com problemas de persistência e possa concentrar-se em resolver

problemas de persistência e possa concentrar-se em resolver problemas de regras de

negócios;

• Aumentar a portabilidade da aplicação: numerosos frameworks de mapeamento

objeto/relacional habilitam o uso da maioria dos bancos de dados relacionais

existentes no mercado para serem usados transparentemente;

A tabela abaixo exibe uma lista com os principais itens que devem ser verificados ao

adquirir uma ferramenta de mapeamento objeto/relacional;

Características Descrição

Herança A ferramenta de desenvolvimento deve ser hábil a projetar um modelo de herança de objetos via relacionamento de tabelas em um banco de dados relacional.

Representar relacionamento entre objetos (1-1, 1-M, M-M) Deve saber como projetar relacionamento entre objetos em bancos relacionais.

Número de BDs Relacionais suportados Possui suporte aos principais BDs. Relacionais (DB2, Oracle, Informix, MSSQLServer, entre outros)

Mecanismos de otimização de performance Quais as funcionalidades para otimizar a performance da ferramentas? Instanciação parcial de objetos, cachê em memória para leitura, etc.

Page 42: Db mapeamento relacional

42

Transações Simples A ferramenta suporta o modelo transacional dos BDs Relacionais?

Suporte e transações aninhadas A ferramenta suporta o modelo de transações aninhadas BDs Relacionais?

4.2. TIPOS DE FERRAMENTAS

4.2.1. Hibernate

É um dos mais bem sucedidos projetos Open Source desenvolvido em Java. Sua

facilidade de uso, abstração e transparência fizeram dele quase um padrão em frameworks

de mapeamento objeto-relacional. Embora sua documentação seja rica e extensa, a falta de

exemplos e dicas em português muitas vezes dificulta a sua adoção por parte de

desenvolvedores brasileiros. O Hibernate não trata apenas do mapeamento de classes Java

em tabelas de banco de dados (e tipos de dados Java em tipo de dados SQL), mas

disponibiliza também um poderoso mecanismo de consulta de dados que pode reduzir

significamente o tempo de desenvolvimento. O Hibernate objetiva “liberar” o

desenvolvedor em 95% das tarefas comum relacionadas à programação de persistência de

dados.

O Hibernate disponibiliza um poderoso framework para persistência objeto-

relacional, de fácil manuseio e alto desempenho. O Hibernate provê suporte para coleções

e relacionamentos entre objetos, assim como herança. polimorfismo e composições. Ele

também tem um rica linguagem de consulta orientada a objetos, o HQL ( Hibernate Query

Language) para recuperação de objetos de banco de dados, uma camada de cachê eficiente

e suporte para Java Management Extensions (JMX).

O Hibernate possui uma comunidade ativa de usuários que ajuda a prover suporte e

ferramentas para extensão. È distribuído de acordo com a Lesser GNU Public License

(LGPL), portanto pode ser usado tanto em explicações de código aberto como comerciais.

Suporta um grande numero de banco de dados, incluindo Oracle e DB2, assim como banco

de dados livres tais como de dados, PostgreSQL e MySQL, permitindo a utilização de

meios nativos para a geração de chaves primarias e pessimistic locking além de resolver

problemas como pool de conexões e configurações de datasources.

Arquitetura

Page 43: Db mapeamento relacional

43

Uma visão de alto nível da arquitetura do Hibernate:

Figura 8: Uma visão simplista do Hibernate

Esta figura mostra o Hibernate usando o banco de dados e a configuração

de dados para disponibilizar serviço de persistência (e objetos persistentes) para a

aplicação.

Dependendo da complexidade do projeto, um maior número de APIs e componentes

são utilizados pelo Hibernate. A figura abaixo exibe uma visão mais detalhada da

arquitetura:

Figura 9: Componentes do Hibernate

Page 44: Db mapeamento relacional

44

De acordo com a especificação do Hibernate, estes componentes são definidos da seguinte

forma:

• SessionFactory (net. sf. hibernate. SessionFactory) Armazena os mapeamentos e

configurações compiladas para um banco de dados. É uma fábrica de objetos Session e

que provê conexões através do ConnectionProvider. Este objeto é imutável e threadsafe

(pode ser acessado por múltiplas threads sem perigo de inconsistência).

• Session (net. sf. Hibernate .Session) Um objeto que representa o "diálogo" entre a

aplicação e a persistência (banco de dados), encapsulando uma conexão JDBC e

manipulado por somente uma thread. Este objeto controla um cache dos objetos

persistentes. Os Session não devem durar toda a execução da aplicação, ou seja, são

objetos de "vida curta".

• Persistent Objects and Collections Objetos manipulados por somente uma thread

que contém as informações persistentes e regras de negócio. Devem ser JavaBeans

(possuir m construtor sem parâmetros e métodos get/set para os atributos persistidos).

Eles só podem estar associados à exatamente uma Session. Assim que o Session é

finalizado, estes objetos são liberados para serem usados em qualquer camada da

aplicação.

• Transient Objects and Collections

Instâncias de classes persistentes que não estão atualmente associadas a um Session.

Podem ter sido instanciados pela aplicação mas ainda não persistidos, ou eles podem ter

sido instanciados por um Session fechado.

• Transaction (net.sf.hibernate.Transaction) Objeto usado pela aplicação para

especificar unidades atômicas de acesso ao banco de dados. Não deve ser manipulado

por múltiplas threads. Abstrai a aplicação dos detalhes das transações JDBC, JTA ou

CORBA. Em alguns casos um Session pode manipular vários Transactions.

Page 45: Db mapeamento relacional

45

• ConnectionProvider (net.sf.hibernate.connection.ConnectionProvider) Uma fábrica

para (e pool de) conexões JDBC. Abstrai a aplicação dos detalhes do Datasource ou

DriverManager. Não exposto à aplicação, mas pode ser estendido/implementado pelo

desenvolvedor.

• TransactionFactory (net.sf.hibernate.TransactionFactory)Uma fábrica para instâncias de

Transaction. Não exposto à aplicação, mas pode ser estendido/implementado pelo

desenvolvedor.

4.2.2. Instalação e Configuração

A última versão Hibernate pode ser copiada do

siteoficial(http://www.hibernate.org). A instalação é simples, bastando descompactar o

arquivo .zip. O diretório criado contém o JAR núcleo do Hibernate (hibernate2.jar).

Também existe um subdiretório chamado lib onde ficam os JARs das outras

APIs utilizadas pelo framework.

Esses arquivos JARs devem ser referenciados no classpath da aplicação. É também

necessário que a classe de driver do seu banco de dados esteja no classpath.

O Hibernate foi desenvolvido para operar em vários ambientes diferentes. Por

isso, existe um grande número de parâmetros de configuração. Por outro lado, a

grande maioria dos parâmetros tem valor padrão e, além disso, o Hibernate é distribuído

com um arquivo chamado hibernate.properties que mostra as várias opções disponíveis.

Você apenas precisa colocar esse arquivo no classpath e customizá-lo.

Configurando o SessionFactory

A tabela abaixo mostra os parâmetros mais importantes para configuração da

conexão JDBC (com banco de dados):

Page 46: Db mapeamento relacional

46

Tabela 2: Parâmetros principais para configuração da conexão JDBC O Hibernate possui ainda uma série de parâmetros que definem seu comportamento

em tempo de execução, como por exemplo:

Tabela 3: Parâmetros que definem comportamento em tempo de execução

O Hibernate trabalha com dialetos para um grande número de bancos de dados, tais

como: DB2, MySQL, Oracle, Sybase, Progress, PostgreSQL, Microsoft SQL Server,

Ingres, Informix entre outros.

Todos estes parâmetros são usados na configuração inicial. A partir deles, é criado um

objeto da classe SessionFactory. Este objeto contém todas as informações passadas na

configuração. Quando criado, o SessionFactory carrega e verifica todas as configurações.

Esta operação consome mais tempo do Hibernate e por isso é recomendável criar este

objeto somente uma vez e utilizá-lo durante toda execução da aplicação. O Hibernate

permite que sejam criados mais de um SessionFactory, mas isso só deve ser feito se houver

necessidade de acesso a mais de um banco de dados. Existem duas formas de informar ao

SessionFactory as configurações do Hibernate:

4.2.3. Configuração através do objeto Configuration

A configuração pode ser feita através da classe Configuration

(net.sf.hibernate.cfg.Configuration). Os objetos desta classe podem ser instanciados de

forma direta. Configuration deve receber as configurações gerais através da classe

Properties e também os mapeamentos Objeto/Relacional (ORM).

Na tabela 4 um exemplo de como criar um SessionFactory através do objeto

Configuration:

Tabela Exemplo 4: Criando um SessionFactory através do objeto Configuration

Page 47: Db mapeamento relacional

47

4.2.4. Mapeamento O/R Básico

O Hibernate usa arquivos XML para mapear os atributos das classes em campos das

tabelas. Qualquer classe pode ser mapeada desde que seja um Bean, ou seja, possua um

construtor sem parâmetros e os atributos mapeados possuam métodos get e set. A presença

de um atributo de identificação (chave primária) é altamente recomendada, mas não é

obrigatória, caso contrário diversas funcionalidades não estarão disponíveis. Não é

necessário nenhum tipo de especialização (herança) ou realização de interface para que uma

classe seja persistida pelo Hibernate. Isto quer dizer que o Hibernate pode persistir objetos

POJO (Plain Old Java Object). Abaixo o exemplo de uma classe que poderia ser persistida:

Tabela Exemplo 5: Classe candidata à persistência

Abaixo, a implementação da classe do diagrama UML acima.

Tabela Exemplo 6: Implementação da classe Pessoa

Segue a declaração de criação da tabela que armazena a classe acima.

Page 48: Db mapeamento relacional

48

Aconselha-se escolher identificadores de tipos de grande capacidade (como

BIGINT) para que um grande número de registros possa ser armazenado. Nota-se o atributo

AUTO_INCREMENT para a chave primária idPessoa, logo em seguida fica claro o porquê

disso.

Tabela Exemplo 7: Declaração de criação da tabela que armazena a classe Pessoa

Para mapear uma classe numa tabela:

Tabela Exemplo 8: Mapeando a classe Pessoa numa tabela

Os arquivos de mapeamento são fáceis de configurar e divididos de maneira

bastante intuitiva. Além disso, a maioria dos parâmetros existentes possui valores padrão.

Este exemplo inicial exibe apenas os parâmetros obrigatórios (com exceção do elemento

<id>).

É obrigatório especificar o nome da classe e a tabela com a qual está associada. O

elemento <id> indica qual é o identificador do objeto e como ele é criado e obtido. Caso ele

seja omitido, o Hibernate considera que a classe não possui identificador. O atributo name

indica que atributo da classe será usado como identificador. O elemento generator informa

como serão gerados os identificadores dos novos elementos. Segue alguns dos tipos de

geradores existentes no Hibernate:

Page 49: Db mapeamento relacional

49

Tabela 9: Tipo de geradores existentes no Hibernate

Cada atributo da classe é mapeado através do elemento <property>. O único

parâmetro obrigatório é o nome do atributo. O Hibernate tentará encontrar uma coluna com

este mesmo nome e definir seu tipo por reflexão. Abaixo, o mapeamento desta mesma

classe com os parâmetros opcionais (usando o mapeamento simples para executar como

exemplo, nota-se que os nomes das colunas foram trocados).

Tabela Exemplo 10: Mapeamento da classe Pessoa com parâmetros opcionais

O primeiro parâmetro a notar é column. Ele indica a coluna correspondente ao

atributo da classe na tabela, caso não tenham o mesmo nome. O parâmetro type, indica o

Page 50: Db mapeamento relacional

50

tipo do atributo Hibernate. Abaixo a associação entre os tipos do Hibernate mais comuns,

as classes wrapper Java e os tipos no banco de dados:

Tabela 11: Associação entre tipos do Hibernate, classes wrapper Java e tipos no BD

No mapeamento, pode ser informado na propriedade type tanto o tipo Hibernate

quando a classe Java. Outra propriedade opcional importante é not-null.

Ela indica que no momento da persistência de um objeto, o determinado atributo

pode ser nulo ou não. Caso um atributo esteja indicado como not-null=”true” e no momento

do salvamento ele esteja null, Hibernate irá lançar uma exceção.

É essencial lembrar de incluir a linha abaixo no arquivo do hibernate.cfg.xml. Ela

indica que este mapeamento deve estar contemplado no SessionFactory.

Tabela Exemplo 12: Mapeamento contemplado no SessionFactory

Page 51: Db mapeamento relacional

51

4.3. Hibernate / Persistência

Hibernate é um mecanismo simples e poderoso que permite a persistência de

objetos em banco de dados relacionais de maneira transparente para qualquer tipo de

aplicação Java. Esta ferramenta, que pode ser baixada gratuitamente da Internet através do

endereço http://hibernate.sf.net/, possibilita que os objetos possam ser gravados e

recuperados a partir de um banco de dados sem que o desenvolvedor tenha que se

preocupar com muitos detalhes. Não há necessidade de se implementar mapeamentos hard-

coded no código Java. O Hibernate resolve problemas como pool de conexões e

configurações de Datasources.

Em linhas gerais, a codificação de um sistema pode ser dividida em duas partes:

regras de negócio e serviços de infra-estrutura. Regras de negócio, como o próprio nome

diz, estão relacionadas ao negócio com o qual o sistema visa trabalhar. Já os serviços de

infra-estrutura estão relacionados à segurança, cache, transação, serviços de nomes, etc. A

idéia do Hibernate é permitir que o desenvolvedor mantenha seu foco sobre as regras de

negócio, liberando-o de parte das tarefas de infra-estrutura.

O Hibernate suporta alguns dos principais bancos de dados relacionais disponíveis

no mercado, permitindo a utilização de meios nativos para geração de chaves primárias e

pessimistic locking. O hibernate trabalha com os bancos de dados através de dialetos,

conforme a tabela 1.

Banco de dados Dialeto DB2 cirus.hibernate.sql.DB2Dialect MySQL cirus.hibernate.sql.MySqlDialect SAPDB cirus.hibernate.sql.SAPDBDialect Oracle cirus.hibernate.sql.OracleDialect Sybase cirus.hibernate.sql.SybaseDialect Progress cirus.hibernate.sql.ProgressDialect McKoiSQL cirus.hibernate.sql.McKoiDialect Interbase/Firebird cirus.hibernate.sql.InterbaseDialect Pointbase cirus.hibernate.sql.PointbaseDialect PostgreSQL cirus.hibernate.sql.PostgreSQLDialect HypersonicSQL cirus.hibernate.sql.HSQLDialect Microsoft SQL Server cirus.hibernate.sql.SybaseDialect

Tabela 13 – Bancos de dados suportados pelo Hibernate

Page 52: Db mapeamento relacional

52

Fonte: www.mundojava.com.br

O desenvolvimento usando Hibernate é um processo que pode ser dividido em cinco

etapas. O primeiro passo é a construção do banco de dados com o qual a aplicação irá

trabalhar, ou seja, criar as tabelas onde os objetos serão persistidos. Este banco de dados,

com suas entidades, atributos e relacionamentos, poderá ser criado de forma tradicional ou,

a critério do usuário, poderá ser utilizada a ferramenta SchemaExport que acompanha o

Hibernate, Esta ferramenta gera o esquema de banco de dados baseado no relacionamento

entre os objetos que se quer persistir. O segundo passo é criação dos objetos cujos estados

vão ser persistidos, isto é, a construção de classes (beans) para cada entidade do banco de

dados. Estas classes devem ser construídas seguindo o modelo JavaBeans, com métodos get

e set para manipulação dos atributos. Neste ponto, o Hibernate difere-se de outros

mecanismos de persistências como o JDO, visto que os beans utilizados pelo Hibernate não

necessitam estender superclasses ou implementar interfaces. É necessária a implementação

de um construtor default (construtor sem parâmetros) para todas as classes persistentes. O

Hibernate faz a instanciação de objetos e o acesso às suas propriedades através de reflexão,

assim métodos de acesso e construtores não necessitam ser declarados como públicos.

Adicionalmente, deve ser criada uma propriedade “chave-primária”, que fará às vezes de

uma primary key, através da qual um objeto será unicamente identificado. Esta propriedade,

não obrigatória, pode ser do tipo primitivo int, long, char ou mesmo uma String.

Após a criação das tabelas e dos beans é necessário criar meta-dados de modo a

fornecer ao Hibernate informações sobre como relacionar os objetos com as entidades do

banco de dados. Esta é a terceira etapa, a criação de arquivos XML que relacionam as

propriedades de cada objeto aos campos das tabelas. Nestes arquivos de mapeamento deve-

se informar, ainda, qual propriedade do objeto se relaciona com a chave-primária, bem com

os relacionamentos entre entidades (inclusive os tipos de relacionamento: 1-1, 1-N ou N-

N).

A quarta etapa refere-se à criação de um arquivo contendo as propriedades

necessárias para que o Hibernate se conecte ao banco de dados. Existe um arquivo de

Page 53: Db mapeamento relacional

53

configuração modelo (hibernate.properties) que poderá ser utilizado como base para que o

usuário proceda à configuração. A quinta e última etapa é a criação de Data Access Objects

(DAO), Tais mecanismos são design pattern úteis para separação da lógica de acesso a

dados da lógica de negócios da aplicação. Estas classes é que conterão os métodos de

inclusão, alteração, exclusão dos objetos, etc.

Em resumo, o Hibernate é uma ferramenta que permite trabalhar com persistência

sobre banco de dados, sem necessidade da inclusão de instruções SQL em meio ao código

Java, assim como elimina a necessidade de se mapear ResultSets e implementar

configuração de pool de conexões, etc., o que torna o código mais legível e,

conseqüentemente, mais fácil de manter. Contudo a implementação não é independente da

fonte de dados, visto que o Hibernate trabalha apenas com alguns dos bancos de dados

relacionais. Por outro lado, caso a aplicação exija consultas SQL complexas, há de se

considerar a utilização da linguagem HQL, a Query Language do Hibernate.

Tabela 14 - Comparações do Hibernate com outros frameworks de persistência

Page 54: Db mapeamento relacional

54

4.5. OJB

O OJB (Object Relational Bridge) faz parte do projeto Jakarta, da fundação Apache,

que desenvolve ferramentas de código aberto para Java. Prestes a ter sua primeira versão

oficial lançada o OJB é baseado em um cerne de mapeamento objeto relacional a partir do

qual várias APIs podem ser disponibilizadas. O OJB e' muito flexivel na forma em que pode

ser usado. O desenvolvedor tem opções de 3 diferentes API:

Uma API compativel com o padrao ODMG 3.0

Uma API compativel com o padrão JDO da Sun (ainda incompleta).

A PersistenceBroker API que server como o núcleo das demais APIs usada no OJB. Essa API

pode ser usada por qualquer tipo de aplicação.

Podemos considerar OJB comparado ao Hibernate em termos de suporte aos conceitos OO

e funcionalidades. O OJB apresenta as vantagens de possuir melhor suporte a distribuição

(com sincronização de cachê) e ser aderente a padrões estabelecidos.

O mapeamento objeto-relacional do OJB é feito através de um único arquivo XML,

cujas marcações fazem parte de um DTD próprio, e para o mapeamento de hierarquias de

classe são permitidos todos os tipos de particionamento (tipado, vertical e horizontal).

Inicialmente foi tentado o mapeamento sobre a mesma base de dados utilizada nos testes do

Hibernate, com particionamento vertical. Contudo, testes preliminares detectaram algumas

falhas do OJB na execução deste tipo de mapeamento. Devido a este problema o programa

de carga utilizado para a geração da base de dados de testes do Hibernate foi modificado

para que também fossem geradas na base tabelas que suportassem o particionamento

horizontal das classes. A base de dados passou então a ser usada tanto pelo Hibernate como

pelo OJB, porém com mapeamentos sobre conjuntos diferentes de tabelas.

A implementação do modelo de classes, em comparação com o Hibernate, foi um

pouco mais complicada. No caso do OJB também foram utilizadas classes simples, apenas

com atributos protegidos e métodos de acesso e modificação.

Contudo, por uma restrição do OJB, para que fosse possível o uso de sua

funcionalidade de carga de objetos sob demanda foi necessário a definição de interfaces, e

fazer que as classes as implementassem, também, de forma semelhante ao caso do

Hibernate, não foi possível declarar algumas das classes como abstratas.

Page 55: Db mapeamento relacional

55

Cliente OJB Layers Backends

Componentes do OJB

● O JDO Suporta:

– Hypersonic SQL

– Lutris InstantDB

– IBM DB2

– Oracle

– MS Access

– MS SQL Server 2000

-Instalar/Configurar

CLIENT APPLICATION

Page 56: Db mapeamento relacional

56

Toda a funcionalidade da versao 1.0 ja esta presente na versao atual. Baixe a versao

binaria do OJB, a menos que você queira dar uma olhada na fonte.

O arquivo que esta disponível para download no web site tem valioas arquivos p/

configurar e criar os tutoriais, e algumas aplicações dentro do OJB. Vou descrever todos os

arquivos necessários para uma aplicação OJB rodar.

-Arquivos

Esses são os arquivos JAR que você precisa no classpath de uma aplicação OJB:

antlr.jar

commons-collections-2.0.jar

commons-dbcp.jar

commons-lang-1.0-mod.jar

commons-pool.jar

db-ojb-1.0.rc2.jar

jta-spec1_0_1.jar

O arquivo OJB.properties contem configurações especificas de como o ambiente OJB

deve rodar. Nele você configura que pool de conexões quer usar, qual a política de cachê a

ser usada, em que arquivo esta a configuração do banco de dados (chamada de repositório),

e varias outras opções. Em geral, não se precisa mudar nada nesse arquivo, mas, ter uma

boa noção e' importante p/ saber que partes do OJB você pode configurar.

Chegou a vez do arquivo mais importante, onde se configura a aplicação que esta

sendo desenvolvida, e o repository.xml, ele contem chamada a outros arquivos XML,

sendo:

-repository_database.xml, contem a configuração do acesso ao banco de dados. Aqui, você

especifica o banco, usuário, senha, enfim, as configurações normais de uma conexão JDBC.

Também se pode setar opções do pool de conexões, como a quantidade máxima e inicial de

conexões a serem abertas.

Page 57: Db mapeamento relacional

57

-repository_user.xml, contem o mapeamento das classes Java as tabelas no banco de dados.

Para cada classe, você deve criar uma definição como esta a seguir:

Code:

<class-descriptor class="br.com.javafree.ojb.Produto" table="jf_produto" > <field-descriptor id="1" name="produtoId" column="produto_id" jdbc-type="INTEGER" primarykey="true" autoincrement="true" /> <field-descriptor id="2" name="descricao" column="produto_desc" jdbc-type="VARCHAR" /> </class-descriptor>

Nesse exemplo, temos uma classe br.com.javafree.ojb.Produto que corresponde a tabela

jf_produto, os campos produto_id e producto_desc correspondem as propriedades id e descrição na classe. A fase de construção do repository_user.xml e' um pouco trabalhosa, mas, os desenvolvedores do OJB esta criando uma aplicação para criar o XML quando você indica a base de dados, o que agilizara muito esse processo. Chegou a vez do código, vou mostrar treis exemplos de operação no banco de dados, uma parte do código é sempre necessária no uso do OJB, que é a chamado ao PersistenceBroker, classe responsável pela operações no banco de dados. Os pacotes org.apache.ojb.broker e org.apache.ojb.broker.query tem que ser importados. SELECIONAR TODOS OS REGISTROS E IMPRIMIR

Code:

PersistenceBroker broker = null; // indicamos que classe queremos buscar no banco de dados Query query = new QueryByCriteria(br.com.javafree.ojb.Produto.class, null); try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); // pedimos ao broker p/ gerar uma colecao como os dados do BD Collection allProducts = broker.getCollectionByQuery(query); // simplesmente imprimos as propriedades dos objetos retornados java.util.Iterator iter = allProducts.iterator(); while (iter.hasNext()) { br.com.javafree.ojb.Produto produto = (br.com.javafree.ojb.Produto)iter.next(); out.println(produto.getId() + " - " + produto.getDescricao() + "<br>"); } } catch (Throwable t) {

Page 58: Db mapeamento relacional

58

t.printStackTrace(); }

INSERIR UM NOVO REGISTRO

Code:

// try to save to DB using OJB br.com.javafree.ojb.Produto novoProduto = new br.com.javafree.ojb.Produto(); novoProduto.setDescricao("Livro de Java "); // ojb PersistenceBroker broker = null; try { broker = PersistenceBrokerFactory.defaultPersistenceBroker(); broker.store(novoProduto); } catch(Exception e) { e.printStackTrace(); }

Para inserir um registro, e' mais simples ainda, basta chamar o método store() do

PersistenceBroker que o OJB se encarrega de armazenar os dados no BD de acordo com o

que definido no arquivo repository_user.xml. Percebam que, pelo fato de termos definido o

campo produto_id como auto incremento, o próprio OJB se encarrega em calcular essa

valor usando a configuração no arquivo OJB.properties. Esse recurso (auto-incremento)

exige o uso de uma tabela interna do OJB, que pode ser criada com o seguinte comando

SQL, no meu caso, p/ MySQL:

Code:

CREATE TABLE `ojb_hl_seq` ( `TABLENAME` varchar(175) NOT NULL default '', `FIELDNAME` varchar(70) NOT NULL default '', `MAX_KEY` int(11) default NULL, `GRAB_SIZE` int(11) default NULL, PRIMARY KEY (`TABLENAME`,`FIELDNAME`) )

5. ESTUDO DE CASO

5.1. DIAGRAMA DE CLASSE “BIBLIOTECA MÚSICA”

Na tabela 15 estão as classe que vão ser utilizada no mapeamento das ferramentas estudadas.

Page 59: Db mapeamento relacional

59

TABELA 15 Diagrama de Classe “Biblioteca Música”;

5.1.2. Modelo de Mapeamento Hibernate:

Definição da classe Artista; Import java.uitl.Set; Import java.util.HashSet; Public class Artista{ private Long id; private String nome; private Set cds = new HashSet(); } Mapeamento da classe Artista <?xml version”1.0” encoding= “UTF-8”?> // cabeçalho do xml <!DOCTYPE hibernate-mapping PUBLIC // cabeçalho do hibernate “-//Hibernate/Hibernate Mapping DTD 2.0//EN” “http://hibernate.sourceforge.net/hibernate.mapping-2.0.dtd”> <hibernate-mapping> <class name= “Artista” table=”artista”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id>

Page 60: Db mapeamento relacional

60

<property Name= “nome” Type= “java.lang.String” Column= “nome” Length= “255” Not-null= “true” /> <set name= “cds”lazy= “true” inverse= “true”> <key column= “artista_id”/> <one-to-many class= “Cd”/> </set> </class> </hibernate-mapping> Definição da classe Cd; Import java.uitl.Set; Import java.util.HashSet; Public class Cd{ private Long id; private String titulo; private Capa capa; private Artista artista; private Set cds = new HashSet(); } Mapeamento da classe Cd; <?xml version”1.0” encoding= “UTF-8”?> // cabeçalho do xml <!DOCTYPE hibernate-mapping PUBLIC // cabeçalho do hibernate “-//Hibernate/Hibernate Mapping DTD 2.0//EN” “http://hibernate.sourceforge.net/hibernate.mapping-2.0.dtd”> <hibernate-mapping> <class name= “Cd” table=”cd”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id> <property Name= “titulo”

Page 61: Db mapeamento relacional

61

Type= “java.lang.String” Column= “titulo” Length= “255” Not-null= “true” /> <set name= “musicas”lazy= “true” inverse= “true”> <key column= “cd_id”/> <one-to-many class= “Musica”/> </set> <many-to-one name=”artista” column= “artista_id” not-null= “true”> <one-to-one name= “capa” class= “Capa”/> </class> </hibernate-mapping> Definição da classe Capa; Import java.uitl.Set; Import java.util.HashSet; Public class Capa{ private Long id; private String imagem; private Cd cd; } Mapeamento da classe Capa; <?xml version”1.0” encoding= “UTF-8”?> // cabeçalho do xml <!DOCTYPE hibernate-mapping PUBLIC // cabeçalho do hibernate “-//Hibernate/Hibernate Mapping DTD 2.0//EN” “http://hibernate.sourceforge.net/hibernate.mapping-2.0.dtd”> <hibernate-mapping> <class name= “Capa” table=”capa”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id> <property Name= “imagem” Type= “java.lang.String”

Page 62: Db mapeamento relacional

62

Column= “imagem” Length= “255” Not-null= “true” /> </class> </hibernate-mapping> Definição da classe Musica; Public class Musica{ private Long id; private String titulo; private Cd cd; } Mapeamento da classe Musica; <?xml version”1.0” encoding= “UTF-8”?> // cabeçalho do xml <!DOCTYPE hibernate-mapping PUBLIC // cabeçalho do hibernate “-//Hibernate/Hibernate Mapping DTD 2.0//EN” “http://hibernate.sourceforge.net/hibernate.mapping-2.0.dtd”> <hibernate-mapping> <class name= “Musica” table=”musica”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id> <property Name= “titulo” Type= “java.lang.String” Column= “titulo” Length= “255” Not-null= “true” /> <many-to-one name=”cd” column= “cd_id” not-null= “true”> </class> </hibernate-mapping>

Page 63: Db mapeamento relacional

63

5.2. Modelo de mapeamento OJB

Definição da classe Artista; Import java.uitl.Set; Import java.util.HashSet; Public class Artista{ private Long id; private String nome; private Set cds = new HashSet(); } Mapeamento da classe Artista <class-descriptor Class=”br.com.javafree.ojb.produto” Table=”jf_produto”> <class name= “Artista” table=”artista”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id> <field-descriptorid=”1” Name= “nome” Type= “java.lang.String” Column= “nome” Length= “255” Not-null= “true” /> <class-descriptor>

Definição da classe Cd; Import java.uitl.Set; Import java.util.HashSet; Public class Cd{ private Long id; private String titulo; private Capa capa; private Artista artista;

Page 64: Db mapeamento relacional

64

private Set cds = new HashSet(); } Mapeamento da classe Cd; <class-descriptor Class=”br.com.javafree.ojb.produto” Table=”jf_produto” > <field-descriptorid=”1” <class name= “Cd” table=”cd”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id> <property Name= “titulo” Type= “java.lang.String” Column= “titulo” Length= “255” Not-null= “true” /> <set name= “musicas”lazy= “true” inverse= “true”> <key column= “cd_id”/> <one-to-many class= “Musica”/> </set> <many-to-one name=”artista” column= “artista_id” not-null= “true”> <one-to-one name= “capa” class= “Capa”/> /> <class-descriptor> Definição da classe Capa; Import java.uitl.Set; Import java.util.HashSet; Public class Capa{ private Long id; private String imagem; private Cd cd; }

Page 65: Db mapeamento relacional

65

Mapeamento da classe Capa; <class-descriptor Class=”br.com.javafree.ojb.produto” Table=”jf_produto” > <field-descriptorid=”1” <class name= “Capa” table=”capa”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id> <property Name= “imagem” Type= “java.lang.String” Column= “imagem” Length= “255” Not-null= “true” /> <class-descriptor> Definição da classe Musica; Public class Musica{ private Long id; private String titulo; private Cd cd; } Mapeamento da classe Musica; <class-descriptor Class=”br.com.javafree.ojb.produto” Table=”jf_produto” > <field-descriptorid=”1” <class name= “Musica” table=”musica”> <id name= “id” column=“id” type=“long” unsaved-value= “null”> <generator class=“native”/> <id>

Page 66: Db mapeamento relacional

66

<property Name= “titulo” Type= “java.lang.String” Column= “titulo” Length= “255” Not-null= “true” /> <class-descriptor>

5.3. Essas são as tabelas do SQL CREATE TABLE Cd ( ID INT NOT NULL, TITULO VARCHAR(30) NOT NULL, CAPA INT NOT NULL, ARTISTA INT NOT NULL PRIMARY KEY (ID), FOREIGN KEY (CAPA) REFERENCES Capa(ID), FOREIGN KEY (ARTISTA) REFERENCES Artista(ID) ); CREATE TABLE Capa ( ID INT NOT NULL, IMAGEM VARCHAR(50), CD INT NOT NULL PRIMARY KEY (ID), FOREIGN KEY (CD) REFERENCES Cd(ID) ); CREATE TABLE Musica ( ID INT NOT NULL, TITULO VARCHAR(30) NOT NULL, CD INT, PRIMARY KEY (ID), FOREIGN KEY (CD) REFERENCES Cd(ID) );

Page 67: Db mapeamento relacional

67

CREATE TABLE Artista ( ID INT NOT NULL, NOME VARCHAR(30), PRIMARY KEY (ID) ); 5.4. Assim seria a inserção nas tabelas uma a uma INSERT INTO Artista (ID, NOME) VALUES (55, ‘João’); INSERT INTO Musics (ID, TITULO, CD) VALUES (123654, ‘MTV AO VIVO’, 53651);

6. RESULTADOS OBTIDOS Todos os testes foram executados em um mesmo ambiente. Para a execução de cada

consulta foi adotado o seguinte procedimento: (1) iniciar o SGBD; (2) iniciar o programa

Page 68: Db mapeamento relacional

68

de execução da consulta; (3) finalizar o SGBD; (4) executar a leitura de arquivos em disco,

não relacionados aos testes, para invalidação de cachês e buffers do sistema operacional.

Antes da execução dos testes de desempenho, porém, foi feito também um teste inicial para

que fosse comprovada a consistência de resultados entre os diversos sistemas testados. Os

conteúdos dos resultados das consultas foram tomados como referência e posteriormente

comparados com os consteúdos dos resultados das consultas executadas pelo Hibernate e o

OJB.

O Hibernate e o OJB apresentam funcionalidades semelhantes aos resumos,

chamadas de consultas escalares e consultas de relatório, respectivamente.

O Hibernate e o OJB também apresentam funcionalidades para distribuição, sendo o

Hibernate mais restritivo e o OJB tendo suporte direto a sincronização de cachê e controle

de concorrência distribuído.

6.1. Vantagens e desvantagens da utilização do mapeamento usando a ferramenta Hibernate Usando a ferramenta:

� O Hibernate torna transparente o acesso ao banco de dados, sendo que ele faz tudo

sozinho, ou seja, ele salva tudo na memória e quando você termina ele salva tudo no

banco.

� O código fica menor e mais eficiente pois o Hibernate otimiza o código.

� Você usa o SQL mas as tabelas são montadas pelo Hibernate.

� Com Hibernate você montaria os objetos mas a inserção ele pegaria cada atributo e

montaria os comandos inserts sozinho.

Não Usando a ferramenta:

� O código seria bem maior.

� Teria que inserir toda as classes usando o SQL sendo que eu teria que montar as

tabelas sendo que o Hibernate já te entrega pronto.

� Todo o acesso ao banco seria manual.

Page 69: Db mapeamento relacional

69

6.2. Vantagens e desvantagens da utilização do mapeamento usando a

ferramenta OJB Usando a ferramenta:

� Fácil de utilizar

� O código fica bem menor

� Ele inseri no banco de dados altomâticamente

Não Usando a ferramenta:

� Não tem a característica de um banco de dados robusto

Por exemplo: indexs, transaccion...

� Não é escalavel

� O código ficaria bem maior

� A inserção ao banco de dados seria manual

7. Conclusão

Page 70: Db mapeamento relacional

70

Apesar da relutância de alguns em adotar esquemas de persistência, fica evidente

que sua utilização trás um ganho considerável de tempo na implementação de um sistema e

eleva a qualidade do produto final, à medida que diminui a possibilidade de erros de

codificação. O fraco acoplamento entre as camadas de dados e de lógica do sistema

promovido pelas Camadas de Persistência é outro ponto que demonstra a sua utilidade.

Além de fornecer um acesso mais natural aos dados, as Camadas de Persistência executam

controle transacional, otimização de consultas e transformações automáticas de dados entre

formatos distinto (tabelas relacionais para arquivos XML ou classes Java, por exemplo).

Sem dúvida, as Camadas de Persistência devem funcionar como a principal ponte de

ligação entre sistemas Orientados a Objetos e repositórios de dados diversos: um conceito

poderoso, com implementações estáveis e comprovadamente eficientes.

Page 71: Db mapeamento relacional

71

8. REFERÊNCIA BIBLIOGRÁFICA

AGILE DATA. “Object-Relational Mapping – An Essay”. [Internet:

http://www.agiledata.org/essays/mappingObjects.html, recuperado em 20/01/2005].

AMBYSOFT. [Internet:http://www.ambysoft.com/mappingObjects.html, recuperado em

20/01/2005].

DATE, C. J. “Introdução a Sistemas de Bancos de Dados”. Rio de Janeiro: Campus, 1990.

HIBERNATE. [Internet: http://www.hibernate.org, recuperado em 16/02/2005].

NASSU, E. A.; SETZER, W. W. “Banco de Dados Orientado a Objeto”. Editora Edgar

Bkucher Ltda., 1º edição 1999.

SILBERSCHATZ, A.; KORTH, H. F., SUDARSHAN, S. “Sistema de Banco de Dados”.

São Paulo: Makron Books, 1999.

MUNDO-OO.“Mapeando Objetos para Bancos de Dados Relacionais: técnicas e

implementações.”[Internet:http://www.mundooo.com.br/php/mooartigos.php?pa=show

page&pid=19, recuperado em 15/03/2005].

ULBRA“Persistência de Dados”[Internet:http://www.ulbra.tche.br/~roland/tcc-

gr/monografias/2003-2-tc2-Anelise_Rosa_Rodrigues.pdf, recuperado em 08/04/2005].

INTERSYSTEMS.“Problemas de Impedância”[Internet:http://www.intersystems.com.br

/isc/downloads/cachedoctec/ProblemadeImpedância.pdf, recuperado em 08/04/2005].

JAKARTA PROJECT. “Projeto Jakarta” [Internet: http://www.jakarta.apache.org

recuperado em 10/10/2005].

Page 72: Db mapeamento relacional

72