SlideShare uma empresa Scribd logo
1 de 72
Baixar para ler offline
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
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
3




Aos meus pais Vital e Maria do Carmo
e irmãos Helinton e Erica.
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;
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)
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.
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
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
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”
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
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.
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].
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
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 é
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
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.
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.
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
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
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.
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).
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
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
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          Uma tabela por          Uma tabela por
                       hierarquia de classes     classe concreta            classe
Ad-hoc reporting       Simples                 Médio                 Médio/Difícil
Facilidade de
                       Simples                 Médio                 Difícil
implementação
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
                       Médio                   Baixo                 Alto
polimorfismos



             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
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;
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
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
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
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
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.
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).
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
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.
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;
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.
36




FIGURA 7 – Uma tabela por classe
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
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.
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.
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.
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.
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
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
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.
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):
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
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.
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:
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
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
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
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
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
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.
55




Cliente                CLIENT APPLICATION




OJB Layers




Backends



                         Componentes do OJB


● O JDO Suporta:


– Hypersonic SQL
– Lutris InstantDB
– IBM DB2
– Oracle
– MS Access
– MS SQL Server 2000




-Instalar/Configurar
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.
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) {
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.
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>
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”
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional
Db mapeamento relacional

Mais conteúdo relacionado

Semelhante a Db mapeamento relacional

Apostila hibernate
Apostila hibernateApostila hibernate
Apostila hibernateAgenor Neto
 
ESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATE
ESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATEESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATE
ESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATEFernando A. Barbeiro Campos
 
Ver
VerVer
Vercsmp
 
Modeloestruturaçaoads
ModeloestruturaçaoadsModeloestruturaçaoads
Modeloestruturaçaoadscsmp
 
4 semestre trabalho individual analise e desenvolvimento de sistemas 2014
4 semestre trabalho individual analise e desenvolvimento de sistemas 20144 semestre trabalho individual analise e desenvolvimento de sistemas 2014
4 semestre trabalho individual analise e desenvolvimento de sistemas 2014WANDERSON JONER
 
Cobo, Cristiane Brandão. Especialização Banco de Dados
Cobo, Cristiane Brandão. Especialização Banco de DadosCobo, Cristiane Brandão. Especialização Banco de Dados
Cobo, Cristiane Brandão. Especialização Banco de Dadoscris.finholdt
 
Algumas das principais características do NoSQL
Algumas das principais características do NoSQLAlgumas das principais características do NoSQL
Algumas das principais características do NoSQLEric Silva
 
Apresentação CMP151
Apresentação CMP151Apresentação CMP151
Apresentação CMP151fgiacomel
 
Banco de dados orientado a objetos
Banco de dados orientado a objetosBanco de dados orientado a objetos
Banco de dados orientado a objetosStefan Horochovec
 
3 oo-concepts
3 oo-concepts3 oo-concepts
3 oo-conceptsjorge600
 
Introdução ao Banco de dados - Prof. Daniel Brandão
Introdução ao Banco de dados - Prof. Daniel BrandãoIntrodução ao Banco de dados - Prof. Daniel Brandão
Introdução ao Banco de dados - Prof. Daniel BrandãoDaniel Brandão
 
Modelos de dados
Modelos de dadosModelos de dados
Modelos de dadosaeasantos
 
Análise Comparativa de Persistência de Dados Entre Hibernate e NHibernate
Análise Comparativa de Persistência de Dados Entre Hibernate e NHibernateAnálise Comparativa de Persistência de Dados Entre Hibernate e NHibernate
Análise Comparativa de Persistência de Dados Entre Hibernate e NHibernateRicardo Rinco
 
Trabalho banco de dados orientado a objetos
Trabalho banco de dados orientado a objetosTrabalho banco de dados orientado a objetos
Trabalho banco de dados orientado a objetoseneck
 
Padroes De Projeto
Padroes De ProjetoPadroes De Projeto
Padroes De Projetoejdn1
 

Semelhante a Db mapeamento relacional (20)

Apostila hibernate
Apostila hibernateApostila hibernate
Apostila hibernate
 
ESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATE
ESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATEESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATE
ESTUDO DE MAPEAMENTO OBJETO-RELACIONAL COM FRAMEWORK HIBERNATE
 
Mapeamento objeto relacional
Mapeamento objeto relacionalMapeamento objeto relacional
Mapeamento objeto relacional
 
Tcc versao final-15-12
Tcc versao final-15-12Tcc versao final-15-12
Tcc versao final-15-12
 
Ver
VerVer
Ver
 
Modeloestruturaçaoads
ModeloestruturaçaoadsModeloestruturaçaoads
Modeloestruturaçaoads
 
4 semestre trabalho individual analise e desenvolvimento de sistemas 2014
4 semestre trabalho individual analise e desenvolvimento de sistemas 20144 semestre trabalho individual analise e desenvolvimento de sistemas 2014
4 semestre trabalho individual analise e desenvolvimento de sistemas 2014
 
Resource Description and Access (RDA)
Resource Description and Access (RDA)Resource Description and Access (RDA)
Resource Description and Access (RDA)
 
Cobo, Cristiane Brandão. Especialização Banco de Dados
Cobo, Cristiane Brandão. Especialização Banco de DadosCobo, Cristiane Brandão. Especialização Banco de Dados
Cobo, Cristiane Brandão. Especialização Banco de Dados
 
Algumas das principais características do NoSQL
Algumas das principais características do NoSQLAlgumas das principais características do NoSQL
Algumas das principais características do NoSQL
 
Apresentação CMP151
Apresentação CMP151Apresentação CMP151
Apresentação CMP151
 
Banco de dados orientado a objetos
Banco de dados orientado a objetosBanco de dados orientado a objetos
Banco de dados orientado a objetos
 
3 oo-concepts
3 oo-concepts3 oo-concepts
3 oo-concepts
 
Cp25540549
Cp25540549Cp25540549
Cp25540549
 
Introdução ao Banco de dados - Prof. Daniel Brandão
Introdução ao Banco de dados - Prof. Daniel BrandãoIntrodução ao Banco de dados - Prof. Daniel Brandão
Introdução ao Banco de dados - Prof. Daniel Brandão
 
Modelos de dados
Modelos de dadosModelos de dados
Modelos de dados
 
Análise Comparativa de Persistência de Dados Entre Hibernate e NHibernate
Análise Comparativa de Persistência de Dados Entre Hibernate e NHibernateAnálise Comparativa de Persistência de Dados Entre Hibernate e NHibernate
Análise Comparativa de Persistência de Dados Entre Hibernate e NHibernate
 
Trabalho banco de dados orientado a objetos
Trabalho banco de dados orientado a objetosTrabalho banco de dados orientado a objetos
Trabalho banco de dados orientado a objetos
 
Padroes De Projeto
Padroes De ProjetoPadroes De Projeto
Padroes De Projeto
 
1345486916110
13454869161101345486916110
1345486916110
 

Último

ANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma AntigaANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma AntigaJúlio Sandes
 
Governo Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 BrasilGoverno Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 Brasillucasp132400
 
Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Centro Jacques Delors
 
Pedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptxPedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptxleandropereira983288
 
Simulado 1 Etapa - 2024 Proximo Passo.pdf
Simulado 1 Etapa - 2024 Proximo Passo.pdfSimulado 1 Etapa - 2024 Proximo Passo.pdf
Simulado 1 Etapa - 2024 Proximo Passo.pdfEditoraEnovus
 
Música Meu Abrigo - Texto e atividade
Música   Meu   Abrigo  -   Texto e atividadeMúsica   Meu   Abrigo  -   Texto e atividade
Música Meu Abrigo - Texto e atividadeMary Alvarenga
 
Universidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comumUniversidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comumPatrícia de Sá Freire, PhD. Eng.
 
trabalho wanda rocha ditadura
trabalho wanda rocha ditaduratrabalho wanda rocha ditadura
trabalho wanda rocha ditaduraAdryan Luiz
 
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptxAD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptxkarinedarozabatista
 
Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)
Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)
Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)Mary Alvarenga
 
Slides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptx
Slides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptxSlides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptx
Slides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptxLuizHenriquedeAlmeid6
 
COMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEM
COMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEMCOMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEM
COMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEMVanessaCavalcante37
 
Manual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envioManual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envioManuais Formação
 
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...ArianeLima50
 
A horta do Senhor Lobo que protege a sua horta.
A horta do Senhor Lobo que protege a sua horta.A horta do Senhor Lobo que protege a sua horta.
A horta do Senhor Lobo que protege a sua horta.silves15
 
D9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptxD9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptxRonys4
 
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptxATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptxOsnilReis1
 
Modelos de Desenvolvimento Motor - Gallahue, Newell e Tani
Modelos de Desenvolvimento Motor - Gallahue, Newell e TaniModelos de Desenvolvimento Motor - Gallahue, Newell e Tani
Modelos de Desenvolvimento Motor - Gallahue, Newell e TaniCassio Meira Jr.
 

Último (20)

ANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma AntigaANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
ANTIGUIDADE CLÁSSICA - Grécia e Roma Antiga
 
Governo Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 BrasilGoverno Provisório Era Vargas 1930-1934 Brasil
Governo Provisório Era Vargas 1930-1934 Brasil
 
Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029Apresentação | Eleições Europeias 2024-2029
Apresentação | Eleições Europeias 2024-2029
 
Pedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptxPedologia- Geografia - Geologia - aula_01.pptx
Pedologia- Geografia - Geologia - aula_01.pptx
 
Simulado 1 Etapa - 2024 Proximo Passo.pdf
Simulado 1 Etapa - 2024 Proximo Passo.pdfSimulado 1 Etapa - 2024 Proximo Passo.pdf
Simulado 1 Etapa - 2024 Proximo Passo.pdf
 
Em tempo de Quaresma .
Em tempo de Quaresma                            .Em tempo de Quaresma                            .
Em tempo de Quaresma .
 
XI OLIMPÍADAS DA LÍNGUA PORTUGUESA -
XI OLIMPÍADAS DA LÍNGUA PORTUGUESA      -XI OLIMPÍADAS DA LÍNGUA PORTUGUESA      -
XI OLIMPÍADAS DA LÍNGUA PORTUGUESA -
 
Música Meu Abrigo - Texto e atividade
Música   Meu   Abrigo  -   Texto e atividadeMúsica   Meu   Abrigo  -   Texto e atividade
Música Meu Abrigo - Texto e atividade
 
Universidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comumUniversidade Empreendedora como uma Plataforma para o Bem comum
Universidade Empreendedora como uma Plataforma para o Bem comum
 
trabalho wanda rocha ditadura
trabalho wanda rocha ditaduratrabalho wanda rocha ditadura
trabalho wanda rocha ditadura
 
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptxAD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
AD2 DIDÁTICA.KARINEROZA.SHAYANNE.BINC.ROBERTA.pptx
 
Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)
Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)
Grupo Tribalhista - Música Velha Infância (cruzadinha e caça palavras)
 
Slides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptx
Slides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptxSlides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptx
Slides Lição 4, Betel, Ordenança quanto à contribuição financeira, 2Tr24.pptx
 
COMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEM
COMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEMCOMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEM
COMPETÊNCIA 1 DA REDAÇÃO DO ENEM - REDAÇÃO ENEM
 
Manual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envioManual da CPSA_1_Agir com Autonomia para envio
Manual da CPSA_1_Agir com Autonomia para envio
 
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
Cultura e Literatura indígenas: uma análise do poema “O silêncio”, de Kent Ne...
 
A horta do Senhor Lobo que protege a sua horta.
A horta do Senhor Lobo que protege a sua horta.A horta do Senhor Lobo que protege a sua horta.
A horta do Senhor Lobo que protege a sua horta.
 
D9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptxD9 RECONHECER GENERO DISCURSIVO SPA.pptx
D9 RECONHECER GENERO DISCURSIVO SPA.pptx
 
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptxATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
ATIVIDADE AVALIATIVA VOZES VERBAIS 7º ano.pptx
 
Modelos de Desenvolvimento Motor - Gallahue, Newell e Tani
Modelos de Desenvolvimento Motor - Gallahue, Newell e TaniModelos de Desenvolvimento Motor - Gallahue, Newell e Tani
Modelos de Desenvolvimento Motor - Gallahue, Newell e Tani
 

Db mapeamento relacional

  • 1. 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
  • 2. 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
  • 3. 3 Aos meus pais Vital e Maria do Carmo e irmãos Helinton e Erica.
  • 4. 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;
  • 5. 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)
  • 6. 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.
  • 7. 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
  • 8. 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
  • 9. 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”
  • 10. 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
  • 11. 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.
  • 12. 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].
  • 13. 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
  • 14. 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 é
  • 15. 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
  • 16. 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.
  • 17. 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.
  • 18. 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
  • 19. 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
  • 20. 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.
  • 21. 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).
  • 22. 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
  • 23. 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
  • 24. 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 Uma tabela por Uma tabela por hierarquia de classes classe concreta classe Ad-hoc reporting Simples Médio Médio/Difícil Facilidade de Simples Médio Difícil implementação 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 Médio Baixo Alto polimorfismos 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
  • 25. 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;
  • 26. 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
  • 27. 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
  • 28. 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
  • 29. 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
  • 30. 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.
  • 31. 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).
  • 32. 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
  • 33. 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.
  • 34. 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;
  • 35. 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.
  • 36. 36 FIGURA 7 – Uma tabela por classe
  • 37. 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
  • 38. 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.
  • 39. 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.
  • 40. 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.
  • 41. 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.
  • 42. 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
  • 43. 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
  • 44. 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.
  • 45. 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):
  • 46. 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
  • 47. 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.
  • 48. 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:
  • 49. 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
  • 50. 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
  • 51. 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
  • 52. 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
  • 53. 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
  • 54. 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.
  • 55. 55 Cliente CLIENT APPLICATION OJB Layers Backends Componentes do OJB ● O JDO Suporta: – Hypersonic SQL – Lutris InstantDB – IBM DB2 – Oracle – MS Access – MS SQL Server 2000 -Instalar/Configurar
  • 56. 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.
  • 57. 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) {
  • 58. 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.
  • 59. 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>
  • 60. 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”