104 1 INTRODUÇÃO A orientação a objeto provê diversos

Propaganda
104
MAPEAMENTO OBJETO-RELACIONAL EM JAVA E PHP
Josiel Silva Moura1
Carlos David Rocha de Souza 1
RESUMO
Atualmente, é comum o uso de bancos de dados relacionais no meio corporativo e da programação orientada a objetos
nas aplicações de interface. Os desenvolvedores frequentemente deparam-se com estes dois paradigmas diferentes: o
modelo relacional e o modelo de objetos. Este estudo tem como objetivo apresentar as principais técnicas de persistência
de objetos, com relevância na técnica de Mapeamento Objeto-Relacional em Java. Compreender os conceitos da técnica
ORM é o primeiro passo para usar efetivamente os frameworks disponíveis.
Palavras-chave: Objeto-Relacional, Banco de Dados, Java, PHP.
ABSTRACT
Currently, it is common to use relational databases in the corporate environment and object-oriented programming
interface for applications. Developers often are faced with these two different paradigms: the relational model and object
model. This study aims to present the main techniques for object persistence, with relevance to the technique of ObjectRelational Mapping in Java. Understand the concepts of ORM technique is the first step to effectively use the available
frameworks.
Key-Words: Object-Relational, Database, Java, PHP.
1 INTRODUÇÃO
A orientação a objeto provê diversos
benefícios em relação a sua predecessora (a análise
estruturada), tais como encapsulamento, polimorfismo,
herança, etc. Essas características proporcionam
soluções muito mais fáceis de representação através da
orientação a objeto traduz os objetos do mundo real da
forma como eles realmente são em oposição à
representação de funcionalidades como era na análise
estruturada. Se, por um lado, as aplicações são
beneficiadas por uma abordagem orientada a objeto, a
persistência dos dados nos bancos relacionais demanda
uma atenção muito maior, pois a tradução entre esses
dois mundos não é direta.
Como existem diferenças conceituais entre o
modelo relacional usados pelos bancos de dados e a
orientação a objetos, acabou surgindo a técnica de
mapeamento objeto-relacional (ORM). Essa técnica
sugere como devemos persistir o estado de um objeto
(atributos, relacionamentos e herança) em tabelas de
banco de dados relacional. Diversas plataformas e
linguagens promovem essa técnica através de
frameworks. Na plataforma Java existe o consagrado
framework Hibernate (Hibernate, 2011) e o padrão
chamado JPA (Biswas, et al., 2006). Em PHP temos o
LUMINE (Lumine, 2008). Já na plataforma .NET
também podemos encontrar o NHibernate (um porte do
Hibernate para .NET) e o Microsoft ObjectSpaces
(Esposito, 2004), dentre outros.
Compreender os conceitos da técnica ORM é
o primeiro passo para usar efetivamente os frameworks
disponíveis. Scott W. Ambler em (Ambler, 2009) e
(Ambler, 2010), descreve minuciosamente essa técnica,
além de discutir o gap conceitual entre o modelo
relacional e a orientação a objetos.
2. MAPEAMENTO OBJETO-RELACIONAL
Grande parte do desenvolvimento de
aplicações modernas utiliza a tecnologia orientada a
On-line http://revista.univar.edu.br/
ISSN 1984-431X
objetos, mas mantém como principal meio de
persistência os bancos de dados relacionais (NASSU,
et al., 1999).
Enquanto o paradigma da orientação a objetos
é baseado em princípios provados pela engenharia de
software, o paradigma relacional é baseado em
princípios matemáticos, especificamente em teoremas
da álgebra relacional. Por consequência das diferenças
entre os dois modelos, há uma dificuldade do ponto de
vista técnico para a implementação rápida e
descomplicada de aplicações que envolvam
programação em linguagem orientada a objetos e o
armazenamento de informações em um SGBD
relacional. Esse é um problema recorrente que recebeu
o nome de "Impedance Mismatch" (Ambler, 2009)
Há uma diferença de representação: os objetos
são referenciados em memória, enquanto os dados são
referenciados por chaves em tabelas, que existem
fisicamente. Além disso, os objetos possuem campos
multivalorados, ao contrário do modelo relacional,
onde os dados devem ser atômicos.
Veremos agora como fazer o mapeamento das
relações da orientação a objetos, 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.
2.1 Chave de Identificação
A forma que os bancos de dados relacionais
encontram para dar unicidade aos seus registros é a
criação de chaves primárias nas tabelas, nas quais
criamos uma coluna cujo valor-chave é não-repetitivo e
não-nulo (Date, 2004).
Os objetos de um sistema não precisam de tal
chave para se tornarem únicos. A unicidade dos objetos
em memória é controlada por mecanismos da própria
linguagem de programação, a qual geralmente oferece
Interdisciplinar: Revista Eletrônica da Univar (2011) nº. 6 p. 104 - 108
105
meios de se referenciar um objeto, ou mesmo de clonar
um objeto já existente, controlando sua identidade por
meio de um OID (Object Identifier) (Dall'Oglio, 2009).
De qualquer forma, dois objetos distintos são
armazenados em regiões diferentes da memória e
referenciados por suas variáveis.
Como compatibilizar então o modelo
conceitual e o modelo de dados da aplicação? A
resposta consiste da criação da chave primária do
registro também para os objetos de negócio da
aplicação. A adoção dessa chave é de suma
importância, uma vez que lemos as informações de um
registro do banco de dados, instanciamos um objeto de
negócio com tais informações, modificamos esse
objeto e, em um dado momento, desejamos armazenar
esse objeto novamente no banco de dados, substituindo
suas informações originais. Isso é possível somente
pela sua chave primária.
3. UMA SITUAÇÃO DE NEGÓCIO
Para demonstrar esses conceitos, imagine que
você possua uma estante repleta de livros e seja
solicitado o desenvolvimento de um sistema para
catalogar os livros e que o principal objetivo desse seja
facilitar a consultar (busca) por um livro. A consulta
deve ser feita pelo título do livro ou pelo autor.
Em nosso sistema, a principal entidade deve
ser o Livro, mas esse depende de algumas outras, tais
como, Editora e Autor, esses não podem ser um
atributo da entidade Livro, pois a Editora possui vários
campos próprios (campo multivalorado) e um Livro
poderá ter vários Autores (campo não-atômico).
Veja abaixo o diagrama de EntidadeRelacionamento simplificada para nosso sistema de
catálogo de livros.
Figura 1:Diagrama criado no MySQL Workbench
(2011)
No mundo relacional um relacionamento um
para um não é visto como uma boa prática de design,
devendo ser utilizado apenas em casos especiais,
conhecidos como particionamento horizontal ou
vertical. Para esse tipo de associação, podemos
adicionar uma chave estrangeira a uma das tabelas,
mapeada para a chave estrangeira da outra tabela
(Amaral, 2008). Dessa forma não abordaremos esse
tipo de relacionamento aqui.
4. RELACIONAMENTO UM-PARA-MUITOS
Observe o diagrama abaixo, ele representa o
relacionamento entre as entidades Livro e Editora. Esse
relacionamento é um relacionamento do tipo um-paraOn-line http://revista.univar.edu.br/
ISSN 1984-431X
muitos, porque uma Editora pode ter muitos Livros
enquanto um livro pode pertencer apenas a uma
editora.
Figura 2: Diagrama de Entidade-Relacionamento
1:1
A
implementação
em
Java
dos
relacionamentos um-para-muitos é relativamente
simples. Na classe de multiplicidade muitos (Livro),
adicione um atributo do tipo da classe de
multiplicidade um (Editora) e os correspondentes
métodos get’s e set’s para esse atributo. Não nos
preocuparemos com os Autores do Livro por enquanto.
4.1 Implementando as Classes de Entidades
Devemos iniciar pela entidade que não possui
dependência, ou seja, que ela exista por si própria, não
dependendo de outras entidades (Deitel, 2005). Assim
iniciaremos a criação a entidade Editora:
01 package entidade;
02 public class Editora {
03
private int codigo;
04
private String nome;
05
private String cidade;
06
private String site;
07
08
public Editora(){
09
}
10
//geteres e seteres omitidos
42 }
Listagem 1: Classe Editora.java
Na classe Livro que possui dependência da
classe Editora, devemos declarar o atributo editora do
tipo Editora. Veja abaixo o código-fonte da entidade
Livro:
01 package entidade;
02 public class Livro {
03
private int codigo;
04
private String titulo;
05
private String categoria;
06
private String edicao;
07
private String ano;
08
private Editora editora;
09
10
public Livro() {
11
}
12
13
//geteres e seteres omitidos
14 }
Listagem 2: Classe Livro.java
4.2
RELACIONAMENTO
MUITOS
MUITOS-PARA-
Interdisciplinar: Revista Eletrônica da Univar (2011) nº. 6 p. 104 - 108
106
Como exemplo desse tipo de relacionamento,
considere a relação livro-autor: um livro pode ser
escrito por vários autores; um autor, por sua vez, pode
escrever vários livros. Na implementação dos
relacionamentos muitos-para-muitos em bancos de
dados relacionais, a solução tem sido usar uma tabela
associativa que represente o relacionamento (Murta, et
al., 2007). Para isso:
 Cria-se uma nova tabela no banco de dados
para representar o relacionamento muitospara-muitos entre duas tabelas;
 Inclue-se como chave estrangeira dessa tabela
as chaves primárias das tabelas que participam
do relacionamento;
 Combina-se essas chaves estrangeiras para
formar a chave primária da tabela associativa
Veja diagrama o Digrama de Entidaderelacionamento para o contexto descrito:
Na entidade Livro, iremos apenas acrescentar
o atributo autores do tipo List da classe java.util.List, e
seus respectivos get’s e set’s.
01 package entidade;
02 import java.util.List;
03 public class Livro {
04
05
private int codigo;
06
private String titulo;
07
private String categoria;
08
private String edicao;
09
private String ano;
10
private Editora editora;
11
private List<Autor> autores;
12
13
public Livro() {
14
}
15
//geteres e seteres omitidos
16 }
Listagem 4: Classe Livro.java modificada
As linhas que acrescentadas estão em destaque
na listagem acima.
Durante o projeto, colunas adicionais podem
ser incluídas nas tabelas, visões que suportem
requisitos de consulta e relatório podem ser criadas e
índices podem ser elaborados para otimizar o
desempenho.
Não
devem
ocorrer
grandes
reestruturações da tabela ao longo do projeto do
sistema, pois isso demonstra que a arquitetura não está
estabilizada.
Figura 3: Diagrama de Entidade-Relacionamento
para livro e autor.
4.3 Implementando as Classes de Entidades
Já na implementação dos relacionamentos
muitos-para-muitos em programação orientada a
objeto, utiliza-se campos multivalorados do tipo
coleção, optou-se aqui por criar uma lista de autores na
entidade Livro, assim iniciaremos a codificação pela
entidade Autor.
01 package entidade;
02
03 public class Autor {
04
private int codigo;
05
private String nome;
06
private String email;
07
08
public Autor() {
09
}
10
//geteres e seteres omitidos
11
12 }
Listagem 3: Classe Autor.java
On-line http://revista.univar.edu.br/
ISSN 1984-431X
5 MAPEAMENTO DE OBJETO RELACIONAL
EM
PHP
UTILIZANDO
TABLE
DATA
GATEWAY
A utilização de mapeamento de objetorelacioal era algo distante quanto ao uso da linguagem
PHP já que a mesma não provia de métodos para
persistência de dados em um banco de dados método o
qual é bem desenvolvido nas plataformas JAVA e .Net.
Em um contexto amplo e geral persistência
significa continuar a existir, perseverar, durar longo
tempo ou permanecer. Em uma linguagem de
programação ou um plano de negócios persistência
significa a possibilidade de esses objetos existirem em
um meio externo à aplicação que os criou, de modo que
esse meio deve permitir que o objeto perdure não deve
ser um meio volátil, meio ao qual os bancos de dados
modelo relacional utilizam tão bem com métodos
específicos de cadê fabricante utilizando a linguagem
SQL para armazenagem e manipulação de dados, mas
existem conceitos na orientação a objetos para os quais
o modelo relacional simplesmente não oferece suporte,
levando ao paradigma de diferentes conceitos, o
modelo relacional que utiliza a codificação estrutural e
o orientado a objeto que trabalha com abstração e
instanciação e encapsulamento de objetos.
A implementação do código abaixo busca
solucionar o problema do banco relação em relação à
síntese de orientação a objeto em PHP. Para mapear o
objeto Editora, foi utilizada a técnica de pattern Table
Data Gateway (Fowler, 2010) que oferece uma
Interdisciplinar: Revista Eletrônica da Univar (2011) nº. 6 p. 104 - 108
107
interface de comunicação com o banco de dados que
permite operações de inserção, alteração, exclusão e
busca de registro. Implementando uma classe
responsável em persistir e retornar dados do banco de
dados. Para isso existem métodos específicos que
traduzem sua função em instruções SQL.
01 <?php
02
03 class EditoraGateway {
04
/*
05
* método insert
06
*/
07
function insert($codigo, $nome, $cidade,
08 $site) {
09
// cria instrução SQL de insert
10
$sql = "INSERT INTO editora (codigo,
11 nome, cidade, site)" .
12
" VALUES ('$codigo', '$nome',
13 '$cidade', '$site')";
14
15
// instancia objeto PDO
16
$conn = new
17 PDO('mysql:host=localhost;port=3306;dbname=l
18 ivros', 'root', '');
19
$conn20 >setAttribute(PDO::ATTR_ERRMODE,
21 PDO::ERRMODE_WARNING);
22
// executa instrução SQL
23
$conn->exec($sql);
24
unset($conn);
25
}
26
27
/*
28
* método update
29
*/
30
function update($codigo, $nome, $cidade,
31 $site) {
32
// cria instrução SQL de UPDATE
33
$sql = "UPDATE editora set nome =
34 '$nome', " .
35
" cidade = '$cidade', site = '$site' " .
36
" WHERE codigo = '$codigo'";
37
38
// instancia objeto PDO
39
$conn = new
40 PDO('mysql:host=localhost;port=3306;dbname=l
41 ivros', 'root', '');
42
$conn43 >setAttribute(PDO::ATTR_ERRMODE,
44 PDO::ERRMODE_WARNING);
45
// executa instrução SQL
46
$conn->exec($sql);
47
unset($conn);
48
}
49
50
/*
51
* método delete
52
*/
53
function delete($codigo) {
54
// cria instrução SQL de DELETE
55
$sql = "DELETE FROM editora where
56 codigo='$codigo'";
On-line http://revista.univar.edu.br/
ISSN 1984-431X
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
10
0
10
1
10
2
10
3
10
4
10
5
10
6
10
7
// instancia objeto PDO
$conn = new
PDO('mysql:host=localhost;port=3306;dbname=l
ivros', 'root', '');
$conn>setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_WARNING);
// executa instrução SQL
$conn->exec($sql);
unset($conn);
}
/*
* método getObject
* busca um registro da tabela editora
*/
function getObject($codigo) {
// cria instrução SQL de SELECT
$sql = "SELECT * FROM editora where
codigo='$codigo'";
// instancia objeto PDO
$conn = new
PDO('mysql:host=localhost;port=3306;dbname=l
ivros', 'root', '');
$conn>setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_WARNING);
// executa consulta SQL
$result = $conn->query($sql);
$data = $result>fetch(PDO::FETCH_ASSOC);
unset($conn);
return $data;
}
/*
* método getObjects
* lista todos registros da tabela editora
*/
function getObjects() {
// cria instrução SQL de SELECT
$sql = "SELECT * FROM editora";
// instancia objeto PDO
$conn = new
PDO('mysql:host=localhost;port=3306;dbname=l
ivros', 'root', '');
$conn>setAttribute(PDO::ATTR_ERRMODE,
PDO::ERRMODE_WARNING);
// executa consulta SQL
$result = $conn->query($sql);
$data = $result>fetchAll(PDO::FETCH_ASSOC);
unset($conn);
return $data;
}
}
// instancia objeto ProdutoGateway
$gateway = new EditoraGateway;
Interdisciplinar: Revista Eletrônica da Univar (2011) nº. 6 p. 104 - 108
108
// insere alguns registros na tabela
$gateway->insert(null, 'Novatec', 'São Paulo',
'www.novatec.com.br');
$gateway->insert(null, 'Moderna', 'São Paulo',
'www.editoramoderna.com.br');
$gateway->insert(null, 'Univar', 'Barra do
Garças', 'www.univar.edu.br');
// efetua algumas alterações
$gateway->update(1, 'Novatec', 'São Paulo - SP',
'www.novatec.com.br');
$gateway->update(2, 'Moderna', 'São Paulo',
'www.moderna.com.br');
// exclui
$gateway->delete(3);
// exibe novamente os registros
echo "Lista de Editoras<br>\n";
print_r($gateway->getObjects());
?>
Listagem 5: Arquivo EditoraGateway.php
Ao trabalhar com Table Data Gateway é
necessário criar uma classe para manipulação de cada
tabela de banco de dados, e apenas uma instancia dessa
classe irá manipular todos os registros da tabela.
6 CONSIDERAÇÕES FINAIS
Este artigo apresentou uma abordagem para o
armazenamento de objetos Java em bancos de dados
relacionais. A principal contribuição deste trabalho é
prover uma solução transparente e acessível para o
problema de mapeamento objeto-relacional.
Apesar da relutância de alguns em adotar
esquemas de persistência, fica evidente que sua
utilização traz um ganho considerável de tempo na
implementação de um sistema e eleva a qualidade do
produto final, à medida que diminui a possibilidade de
erros de codificação.
O mapeamento objeto relacional pode ser feito
tanto manualmente quanto automaticamente. O
processo de mapeamento objeto relacional manual, que
foi abordado neste artigo, é trabalhoso, pois torna-se
necessário definir, para cada classe do sistema, como
esta se relaciona e como será armazenada. Já o
processo automático, suportado por uma ferramenta de
mapeamento torna esse processo mais simples, mas
nem sempre o torna transparente. Assim este trabalho
cumpri o objetivo de mostrar a transparência desse
processo, para em um trabalho futuro mostrar como é
feito em um processo automatizado utilizando um
framework disponível.
7 REFERENACIA BIBLIOGRÁFICAS
AMARAL, Fernando. Dicas de Mapeamento
Objeto/Relacional.
2008.
Disponivel
em
<http://www.fernandoamaral.com.br/Default.aspx?Arti
go=55>. Acessado em 21 de abril de 2011.
em
<http://www.agiledata.org/essays/mappingObjects.html
>. Acessado em 20 de abril de 2011.
_________
The
Object-Relational
Impedance
Mismatch.
2009.
Disponivel
em
<http://www.agiledata.org/essays/impedanceMismatch.
html>. Acessado em 16 de abril de 2011.
BISWAS, Rahul and Ort. The Java Persistence API - A
Simpler Programming Model for Entity Persistence.
2006.
Disponivel
em
<http://www.oracle.com/technetwork/articles/javaee/jp
a-137156.html>. Acessado em 30 de maio de 2011.
DALL'OGLIO, Pablo. PHP: programando com
orientação a objetos. São Paulo : Novatec Editora,
2009.
DATE, C.J. Introdução a Sistemas de Bancos de
Dados. São Paulo : Campus, 2004.
DEITEL, Paul J. Java: Como Programar. 6ª ed.
Prentice-Hall, 2005.
ESPOSITO, Dino. A First Look at ObjectSpaces in
Visual Studio 2005. 2004. Disponivel em
<http://msdn.microsoft.com/enus/library/ms971512.aspx>. Acessado em 23 de maio
de 2011.
FOWLER, Martin. Table Data Gateway. 2010.
Disponivel
em
<http://martinfowler.com/eaaCatalog/tableDataGatewa
y.html>. Acessado em 20 de abril de 2011.
HIBERNATE. Hibernate - JBoss Community. 2011.
Disponivel em <http://www.hibernate.org/>. Acessado
em 10 de abril de 2011.
LUMINE. Lumine - Database Mapping for PHP. 2008.
Disponivel em <http://www.hufersil.com.br/lumine.>.
Acessado em 23 de abril de 2011.
MURTA, Leonardo Gresta Paulino, Veronese, Gustavo
Olanda and Werner, Cláudia Maria Lima. MOR: Uma
Ferramenta para o Mapeamento. Rio de Janeiro :
UFRJ, 2007.
MySQL. MySQL Workbench. 2011. Disponivel em
<http://wb.mysql.com>. Acessado em 25 de maio de
2011.
NASSU, E. A. and SETZER, W. W. Banco de Dados
Orientado a Objeto. 1ª Edição. Editora Edgar Bkucher
Ltda, 1999.
AMBLER, Scott W. Mapping Objects to Relational
Databases: O/R Mapping In Detail. 2010. Disponivel
On-line http://revista.univar.edu.br/
ISSN 1984-431X
Interdisciplinar: Revista Eletrônica da Univar (2011) nº. 6 p. 104 - 108
Download