Object-Relational Mapping(ORM) - Mapeamento de Objeto-Relacional
Mapeamento de Objeto-Relacional (ORM) é uma abordagem que permite a construção de sistemas utilizando o paradigma orientado a objetos com a persistência destes objetos em bancos de dados relacionais. Utilizando-se de técnicas e estratégias específicas, é possível mapear classes com seus atributos e associações para o modelo relacional (SILVA et al.; 2006).
Segundo (AMBLER, 1999), “o mapeamento de classes pode ser feito mediante a paridade entre classe e tabela, ou seja, uma classe é mapeada para uma tabela”. Este mapeamento direto de classes para tabelas representa a forma mais simples de mapeamento, tornando mais fácil o entendimento e a manutenção de uma aplicação. A idéia deste mapeamento pode ser visualizada na Figura 1.
Figura 1: Mapeamento de Tabelas - Simples
Porém, nem sempre o mapeamento é tão simples assim. No caso de uma estrutura hierárquica, várias classes podem ser mapeadas para uma tabela, bem como uma classe pode ser mapeada para várias tabelas. Esse mapeamento mais complexo de classes e tabelas pode ser observado na Figura 2.
Figura 2: Mapeamento de Tabelas - Complexo
As tabelas Classe1 e Classe2 possuem, respectivamente, relacionamento com as tabelas Tabela1 e Tabela3. Esse mapeamento seria de certa forma trivial, e poderia ser tratado como relacionamento simples. Um terceiro relacionamento feito pelas duas tabelas impossibilita esse tratamento, pois ambas possuem atributos na Tabela2. Dessa forma é necessário que haja uma especificação de quais atributos pertencem a cada classe na Tabela2.
Ao tratar do mapeamento de atributos de uma classe para colunas em tabelas de um banco de dados relacional, deve-se levar em conta que os atributos podem ser de tipos de dados primitivos como inteiros, pontos flutuantes, caracteres, booleanos e binários, bem como ser de tipos de dados complexos como tipos baseados criados pelo usuário. Os atributos podem ser ainda multivalorados, o que viola as regras de normalização do modelo relacional.
Além disso, podem existir atributos de controle ou utilizados em cálculos, que geralmente não necessitam serem mapeados (AMBLER, 1999). Desta forma, os atributos simples podem ser mapeados diretamente para colunas em uma tabela, já os atributos complexos e multivalorados podem necessitar de tabelas adicionais para seu armazenamento. Estes atributos complexos, geralmente, possuem características recursivas, ou seja, são classes que possuem outros atributos e, assim, sucessivamente.
O mapeamento segue o seguinte conceito: as classes mapeiam cada uma das tabelas do banco de dados de modo que as linhas dessas tabelas se tornam objetos e as colunas referem-se aos atributos dessa classe. Esse conceito pode ser visualizado na Figura 3.
Figura 3: Mapeamento de Tabelas, Objetos e Atributos
Essa técnica possibilita mais do que códigos limpos, permite que persistências de objetos no banco de dados sejam feitas sem simples e transparente.
O ORM se comporta como uma camada que possui uma gama de métodos que cuidam dessa tarefa, tais como: create (cria um novo objeto da classe a partir dos dados da tabela), find (busca um determinado registro no banco e o torna um objeto da classe), delete (exclui registros do banco) e update (atualiza registros de uma tabela de acordo com as solicitações). Esses métodos variam de acordo com a linguagem utilizada.
Na Tabela 1, é possível observar um pouco das facilidades e de como a legibilidade do código fica melhor ao se utilizar o ORM ao invés de se injetar dentro de seu código o SQL puro, o que fere as boas práticas de programação, que sugere que códigos SQL estejam separados dos códigos de desenvolvimento (RODRIGES; COSTA; SILVEIR, 2001).
Essa camada, chamada de persistência, encontra-se entre a camada de negócio (onde estão as classes de domínio da aplicação, ou seja, classes que definem as regras de negócio) e o banco de dados. Esta camada permite que o impacto das modificações em uma delas seja atenuado em relação à outra. Isto diminui o grau de dependência do banco de dados e aumenta a facilidade de manutenção do código. Na Figura 4 pode-se analisar a disposição dessas camadas.
Figura 4: Camada de Persistência
Toda responsabilidade por persistir objetos fica a cargo da camada de persistência, liberando a aplicação destas tarefas, e assim aumentando a produtividade no desenvolvimento (YODER; JOHNSON; WILSON,1998). Na camada de persistência está a definição das estratégias de mapeamento do modelo orientado a objetos para o modelo relacional, apresentadas anteriormente.
A camada de classes representa todo o conjunto de classes (controllers, views dentre outras) que podem utilizar métodos da camada de persistência. Assim, as transações com o banco de dados ficam transparentes.
Artigo da série: