Object Relational Mapping

Artigo que explica o que é ORM - Object Relational Mapping - e discute seus benefícios e contrapartidas.

Bom, para meu primeiro post efetivo sobre tecnologia, resolvi escrever sobre algo bastante alto nível e, de repente, pouco conhecido entre programadores PHP: ORM. Pretendo, inicialmente, mostrar o conceito e, em posts futuros, talvez aprofundar em mais detalhes.

ORM, em português, pode ser traduzido como Mapeamento Objeto-Relacional. Trata-se de uma técnica usada sobre sistemas baseados no POO que utilizam bases de dados relacionais (que ainda são as mais comuns, enquanto os bancos de dados orientados a objetos estão evoluindo). A técnica consiste em mapear as tabelas do BD em classes da aplicação. De forma análoga, as colunas de uma tabela do BD são mapeadas em atributos da respectiva classe da aplicação.


Um exemplo de ORM

Temos a seguinte tabela no BD:

CREATE TABLE usuarios (
  id INTEGER NOT NULL AUTO_INCREMENT,
  login VARCHAR(50) NOT NULL DEFAULT '',
  senha VARVAR(32) NOT NULL DEFAULT '',
  PRIMARY KEY (id)
);

Na aplicação, poderiamos ter a seguinte classe que representa a tabela "usuarios":

class usuario extends classe_base {
    protected $id;
    protected $login;
    protected $senha;

    ...
}


Objetivo do ORM

Não sei dizer, com exatidão, o principal objetivo da técnica, mas eu cito estes como relevantes:

  • Unificar a camada DAO. Ela permite que consultas e operações sobre o BD sejam feitos dinamicamente, através de métodos. Com isso, a criação de SQL pode se tornar desnecessária.
  • Torna o desenvolvimento mais ágil, já que o código se torna mais alto nível.
  • Pode tornar o desenvolvimento mais seguro, já que a camada responsável pelo ORM pode tratar algumas questões como SQL Injection, que é um tipo de falha de segurança.


Comentários

Sei que PHP possui classes de terceiros que dão suporte ao ORM, porém, nunca utilizei nenhuma delas. Em todo caso, conheço o conceito pois implementei minha própria camada que trata do ORM. Sem dúvidas imlementar um ORM não é nada trivial, especialmente se esta implementação suportar diferentes tipos de Bancos de Dados. Como cada Banco de Dados possui suas características próprias, tipos próprios e sintaxe própria, implementar algo que gera SQL de acordo com o SGBD é complexo. Além do mapeamento básico citado acima, também é preciso realizar um mapeamento de tipos, ou seja, o tipo de dado oferecido pelo banco de dados ser mapeado em algum tipo de dados da linguagem de programação utilizada. Por exemplo: VARCHAR do BD se tornar string na aplicação.

O nível da complexidade aumenta ainda mais quando são tratados também os relacionamentos entre tabelas (que geram chaves estrangeiras). Neste caso, conseguimos situações bastante interessantes: por exemplo, uma classe que mapeia uma tabela com relacionamento pode ter um atributo que representa o relacionamento (o valor da chave relacionada) e ter um outro atributo que "aponta" para outro objeto.

Por exemplo, se temos uma tabela "professor" que possui relacionamento com a tabela "pessoa", poderiamos ter um código parecido com isso:

$professor = new professor();
$professor->siape = '123';
$professor->pessoa->nome = 'Teste da Silva';
$professor->pessoa->cpf = '12345678901';

Bom, eu acho que minha implementação de ORM foi uma das coisas mais complexas que já fiz. Em todo caso, ajuda muito. Você já ouviu falar de JPA da linguagem Java? Trata-se de um framework de persistência de dados que possibilita a utilização de ORM.

2 comentários

Everton Henrique disse...

Assunto interessante.
Tenho pensado em projetos maiores e um dos desafios maiores pra mim é estruturar (com orientação a objetos) a relação da aplicação com os dados.

Mas Rubens, me corrija se eu estiver errado:
Andei lendo algo sobre Design Patterns.
Por acaso, um design pattern não seria melhor do que essa técnica de ORM?
Pelo que entendi, ambos tem o mesmo objetivo, mas o design pattern parece fazer a mesma coisa com menos código... É certo isso?

Abraços!

Rubens Takiguti Ribeiro (autor do blog) disse...

Everton: utilizei ORM em projeto grande e o maior desafio foi modelar a base de forma consistente o suficiente para prover escalabilidade sem afetar muito a estrutura criada. Pois se um novo requisito exige mudanças no esquema do BD, reflete impactos na implementação.

Design Patterns é um conjunto de técnicas e ORM é uma única técnica. Talvez você possa comparar ORM com o design DAO, e, como quase tudo na computação, creio que não exista um melhor. O importante é conhecer as diferenças e pesar os prós e contras para cada situação.

Na prática, você consegue até implementar um DAO que utiliza ORM em mais baixo nível, fazendo uma abordagem mista.