Programação orientada a objetos e banco de dados relacional: como mapear dependências, agregações, composições e heranças

Filed Under (Banco de dados) by Antonio Passos on 02-03-2009

Tagged Under : , , , ,


A questão é antiga, a resposta, conhecida, mas ainda assim atormenta estudantes de programação orientada a objetos e mesmo profissionais TI: como fazer o mapeamento das relações complexas (como dependência, agregação, composição e herança) entre os objetos de um programa orientado a objetos para bancos de dados relacionais, os quais armazenam dados em linhas e colunas de tabelas que mantêm ligações lógicas entre si pela utilização de chaves estrangeiras? 

A solução, sabemos, para o armazenamento de objetos em bancos de dados relacionais passa pela adoção de técnicas de mapeamento objeto-relacional vista neste artigo.

Considere o diagrama de classes abaixo (clique na imagem para visualizá-la em tamanho maior):

FastPrato - Diagrama de classes

Trata-se do diagrama de classes de um hipotético aplicativo (JPratosProntos) que registra pedidos de refeições (pratos) por telefone:

Que tipos de relacionamentos vemos ali? São eles:

  • Relacionamentos de dependência entre:
    • Pedido e Cliente;
    • Pedido e Funcionario
    • Prato e ItemDoPedido
  • Relacionamentos de composição entre:
    • Pessoa e Endereco;
    • Pessoa e Telefone
    • Pessoa e Email;
    • Pedido e ItemDoPedido
  • Relacionamento de agregação entre
    • Prato e Fornecedor
  • Relacionamentos de herança entre
    • Pessoa e PessoaFisica;
    • Pessoa e PessoaJuridica;
    • PessoaFisica e Cliente;
    • PessoaFisica e Funcionario

Uma vez que esses objetos e suas relações tenham que ser armazenados em um banco de dados relacional (por exemplo, no H2), como seria o modelo físico desse banco de dados? Abaixo, uma solução possível (clique na imagem para visualizá-la em tamanho maior):

Analise como foram feitos os mapeamentos. Por exemplo:

  • O mapeamento do relacionamento de dependência entre as classes Pedido e Cliente foi feito para uma chave estrangeira (FK) na tabela Pedido que aponta para a chave primária  (codcliente) da tabela Cliente. 
  • O relacionamento de composição entre as classes Pessoa e Endereco foi mapeado para uma chave estrangeira (FK) na tabela Endereco que aponta para a chave primária (cdpessoa) da tabela Pessoa; essa chave estrangeira (cdpessoa) constitui a chave primária da tabela Endereco. 
  • O relacionamento de agregação entre as classes Prato e PessoaJuridica (fornecedor) foi mapeado para uma tabela associativa cuja chave primária é uma combinação das chaves primárias das tabelas Prato e PessoaJuridica (fornecedor). Se não estivéssemos diante de um relacionamento muitos-para-muitos, a solução seria a mesma usada para mapear um relacionamento de dependência.
  • O mapeamento do relacionamento de herança entre as classes Pessoa e PessoaFisica foi feito para uma chave estrangeira (FK) na tabela PessoaFisica que aponta para a chave primária (cdpessoa) da tabela Pessoa; essa chave estrangeira constitui a chave primária da tabela PessoaFisica.

Há duas outras formas de mapear o  relacionamento de herança: usando uma única tabela ou tabelas independentes. Essas soluções, entretanto, são questionáveis do ponto de vista da normalização, sendo preferível a que usei no exemplo na qual se tem uma tabela para cada classe.  

É isso, pessoal. Para criar as tabelas do JPratosProntos no banco de dados H2, use ESTE SCRIPT SQL.

Para saber como implementar a persistência de relacionamentos muitos-para-muitos em Java, leia ESTE ARTIGO.

Referências consultadas:

FOWLER, Martin. Padrões de arquitetura de aplicações corporativas. Porto Alegre: Bookman, 2006.
LARMAN, Craig. Utilizando UML e padrões. Porto Alegre: Bookman, 2004.
HORSTMANN, Cay. Padrões e projeto orientados a objetos. Porto Alegre: Bookman, 2007.
MACHADO, Felipe Nery Rodrigues. Banco de dados: projeto e implementação. São Paulo: Érica, 2004.

Leia também este(s) post(s)...


Comments:

Post a comment