Mapeamento Objeto-Relacional da Teoria à Prática
Salve comunidade!
Neste artigo irei falar resumidamente sobre mapeamento objeto-relacional que consiste em uma abordagem que permite a construção de sistemas utilizando o paradigma da orientação a objetos com a persistência destes objetos em bancos de dados relacionais como o Mysql.
Utilizando-se de técnicas e estratégias específicas, é possível mapear classes com seus atributos e associações para o modelo relacional.
Os bancos de dados orientados a objeto são mais adequados para a persistência de objetos manipulados por aplicações orientadas a objeto, devido à utilização do mesmo paradigma. Porém a indisponibilidade atual destes bancos de dados, seja devido ao custo, diversidade ou amadurecimento do mercado, faz com que seja necessária a busca de alternativas para a realização da persistência.
Desenvolvendo projetos desta maneira você estará contribuindo para a reutilização do seu código em diferentes áreas do seu sistema e até mesmo de projetos futuros, sem falar da legibilidade e do aspecto profissional agregados ao seu código.
Mais como seria esse mapeamento na prática?
Suponha que tenhamos as seguintes tabelas do DER abaixo no nosso banco de dados:
A partir delas iremos construir nossas classes, lembrando que a ordem não importa, conheço algumas pessoas que costumam fazer a modelagem do banco de dados primeiro, depois as tabelas e outras que modelam primeiro seus objetos para somente então, partir para a construção do DER.
Abaixo está o diagrama de classes que representa as tabelas do DER:
Obs.: Sinais de visibilidade de atributos e métodos utilizados seguindo os padrões da UML
Onde o sinal de "+" => private; "-" => public; "#" => protected
No diagrama de classes, cada tabela do banco de dados foi mapeada para uma classe, onde o nome da classe é o mesmo nome da tabela só que no singular e sem o prefixo.
Os atributos possuem visibilidade private, ou seja, somente os métodos internos a classe é que poderão acessá-los diretamente, para objetos externos acessarem estes atributos, deve-se utilizar as propriedades modificadoras, os famosos get e set, se o atributo for somente de leitura você pode omitir a propriedade set.
O método __construct pode ser utilizado para setar os valores default de cada atributo.
Relacionamentos:
No DER temos o relacionamento 1 para n indicando que uma categoria pode conter nenhum ou vários clientes, porém um cliente só está ligado a uma categoria.
Para construir o relacionamento inserimos a chave estrangeira cli_idCategoria na tabela de clientes ligando-a com a chave primária cat_id da tabela de categorias.
No diagrama de classes também temos os atributos cli_idCategoria e cat_id, só que como o objeto Cliente é responsável por conhecer a sua categoria, criamos o atributo objCategoria na classe Cliente, desta forma, assim que utilizarmos o método $objCliente->carregar(), este terá que chamar o método $this->objCategoria->carregar().
Estes métodos devem recuperar os dados de um determinado registro no banco e setá-los em cada atributo do objeto.
Para que possamos identificar qual registro deve ser recuperado, setamos o id do objeto:
A implementação dos métodos CRUD (Create, Read, Update e Delete), ou seja, cadastrar, carregar, alterar e excluir, vai depender de quantas camadas sua aplicação estará dividida.
O ideal é que nas classes Cliente e Categoria você só realize operações envolvidas com a camada de negócios, fazendo com que estes métodos chamem outros métodos de uma camada de nível mais baixo, como por exemplo DaoCliente::carregar() e DaoCategoria::carregar(). (Dao vem de Data Access Object)
Estas classes sim é que poderiam ter métodos com cláusulas SQL como SELECT, INSERT, UPDATE E DELETE.
Da mesma forma, você pode criar classes de nível mais alto para gerenciar a camada de apresentação, nestas classes você irá tratar códigos HTML, Javascript, CSS e etc.
Codificando desta forma seus objetos ficarão muito mais reutilizáveis!!
Então chega de conversa e mãos a obra! Na próxima página postei o código fonte das classes...
Neste artigo irei falar resumidamente sobre mapeamento objeto-relacional que consiste em uma abordagem que permite a construção de sistemas utilizando o paradigma da orientação a objetos com a persistência destes objetos em bancos de dados relacionais como o Mysql.
Utilizando-se de técnicas e estratégias específicas, é possível mapear classes com seus atributos e associações para o modelo relacional.
Os bancos de dados orientados a objeto são mais adequados para a persistência de objetos manipulados por aplicações orientadas a objeto, devido à utilização do mesmo paradigma. Porém a indisponibilidade atual destes bancos de dados, seja devido ao custo, diversidade ou amadurecimento do mercado, faz com que seja necessária a busca de alternativas para a realização da persistência.
Desenvolvendo projetos desta maneira você estará contribuindo para a reutilização do seu código em diferentes áreas do seu sistema e até mesmo de projetos futuros, sem falar da legibilidade e do aspecto profissional agregados ao seu código.
Mais como seria esse mapeamento na prática?
Suponha que tenhamos as seguintes tabelas do DER abaixo no nosso banco de dados:
+------------------------+
|cli_clientes | +--------------------------+
+------------------------+ |cat_categorias |
|cli_id int(10) | +--------------------------+
|cli_idCategoria int(10) | n ------------- 1 |cat_id int(10) |
|cli_nome varchar(50) | |cat_nome varchar(50) |
|cli_cpf varchar(20) | +--------------------------+
|cli_email varchar(30) |
+------------------------+
A partir delas iremos construir nossas classes, lembrando que a ordem não importa, conheço algumas pessoas que costumam fazer a modelagem do banco de dados primeiro, depois as tabelas e outras que modelam primeiro seus objetos para somente então, partir para a construção do DER.
Abaixo está o diagrama de classes que representa as tabelas do DER:
Obs.: Sinais de visibilidade de atributos e métodos utilizados seguindo os padrões da UML
Onde o sinal de "+" => private; "-" => public; "#" => protected
+----------------------------------+
| Cliente | +------------------------------+
+----------------------------------+ | Categoria |
|+ int cli_id | +------------------------------+
|+ int cli_idCategoria | ----------------> |+ cat_id |
|+ Categoria objCategoria | |+ cat_nome |
|+ string cli_nome | +------------------------------+
|+ string cli_cpf | |- setId($intId) |
|+ string cli_email | |- getId() |
+----------------------------------+ |- setNome($strNome) |
|- setId($intId) | |- getNome() |
|- getId() | |- __construct() |
|- setIdCategoria($intIdCategoria) | |- __destruct() |
|- getIdCategoria() | |- cadastrar() |
|- setCategoria($objCategoria) | |- alterar() |
|- getCategoria() | |- excluir() |
|- setNome($strNome) | |- carregar() |
|- getNome() | |- listar() |
|- setCpf($strCpf) | +------------------------------+
|- getCpf() |
|- setEmail($strEmail) |
|- getEmail() |
|- __construct() |
|- __destruct() |
|- cadastrar() |
|- alterar() |
|- excluir() |
|- carregar() |
+----------------------------------+
No diagrama de classes, cada tabela do banco de dados foi mapeada para uma classe, onde o nome da classe é o mesmo nome da tabela só que no singular e sem o prefixo.
Os atributos possuem visibilidade private, ou seja, somente os métodos internos a classe é que poderão acessá-los diretamente, para objetos externos acessarem estes atributos, deve-se utilizar as propriedades modificadoras, os famosos get e set, se o atributo for somente de leitura você pode omitir a propriedade set.
O método __construct pode ser utilizado para setar os valores default de cada atributo.
Relacionamentos:
No DER temos o relacionamento 1 para n indicando que uma categoria pode conter nenhum ou vários clientes, porém um cliente só está ligado a uma categoria.
Para construir o relacionamento inserimos a chave estrangeira cli_idCategoria na tabela de clientes ligando-a com a chave primária cat_id da tabela de categorias.
No diagrama de classes também temos os atributos cli_idCategoria e cat_id, só que como o objeto Cliente é responsável por conhecer a sua categoria, criamos o atributo objCategoria na classe Cliente, desta forma, assim que utilizarmos o método $objCliente->carregar(), este terá que chamar o método $this->objCategoria->carregar().
Estes métodos devem recuperar os dados de um determinado registro no banco e setá-los em cada atributo do objeto.
Para que possamos identificar qual registro deve ser recuperado, setamos o id do objeto:
<?php
$objCliente = new Cliente;
$objCliente->setId('3');
$objCliente->carregar();
echo $objCliente->getNome();
echo $objCliente->getCpf();
echo $objCliente->getCategoria()->getNome();
?>
A implementação dos métodos CRUD (Create, Read, Update e Delete), ou seja, cadastrar, carregar, alterar e excluir, vai depender de quantas camadas sua aplicação estará dividida.
O ideal é que nas classes Cliente e Categoria você só realize operações envolvidas com a camada de negócios, fazendo com que estes métodos chamem outros métodos de uma camada de nível mais baixo, como por exemplo DaoCliente::carregar() e DaoCategoria::carregar(). (Dao vem de Data Access Object)
Estas classes sim é que poderiam ter métodos com cláusulas SQL como SELECT, INSERT, UPDATE E DELETE.
Da mesma forma, você pode criar classes de nível mais alto para gerenciar a camada de apresentação, nestas classes você irá tratar códigos HTML, Javascript, CSS e etc.
Codificando desta forma seus objetos ficarão muito mais reutilizáveis!!
Então chega de conversa e mãos a obra! Na próxima página postei o código fonte das classes...
Diego parabéns pelo artigo, excelente mesmo, são poucos que tem essa mentalidade de OO, muitos não sabem o que é e outros não sabem como implementar, esse seu artigo ficou muito bom, uma unica duvida que eu fiquei é de como q ficaria a implementação desse DAO, já ouvi falar disso mas não pesquisei nada ainda se puder colocar mais um artigo explanando sobre esse assunto acho q seria bem interressante, ou se tiver algum material e puder me enviar fico muito grato.
Parabéns.
Parabéns.
30/07/2007 9:11am
(~18 anos atrás)
Lembrando que o design pattern que você usou é o Active Record (http://www.martinfowler.com/eaaCatalog/activeRecord.html) e o Data Access Object (http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html).
No caso do Active Record, um ponto contra é que as rotinas de persistência estão fortemente acopladas ao objeto, o que pode não ser o cenário ideal para todas as situações. Algumas vezes é melhor separar as rotinas de cadastro, exclusão, seleção e atualização em um objeto separado. ;)