Você está na página 1de 18

UNIVERSIDADE ZAMBEZE

FACULDADE DE CIÊNCIAS E TECNOLOGIA


ENGENHARIA INFORMÁTICA
2° Ano – Laboral
PROGRAMAÇÃO ORIENTADA A OBJECTO II
Tema:
Persistencia em Java(Frameworks)

Nomes:
Lingui Joaquim Moiana
Lucas Luis Paunde
Paulo Samuel Ernesto Tinga

Docente:

Michael Karagian Mesquita

Beira, Novembro de 2022


Indice
Introduçao
Objetivo geral
Este artigo tem por objetivo realizar uma análise comparativa dos frameworks de
persistência, evidenciar o desempenho dos mesmos, apresentar técnicas de mapeamento,
comparar a produtividade, detalhar suas especificações e apontar os pontos fracos e
pontos fortes

Objectivos especificos

Justificativa

Analisando os sistemas desenvolvidos nos dias de hoje, é visível a necessidade de


armazenamento de dados presente, sejam eles sistemas organizacionais, empresariais,
pessoais, ou até mesmo acadêmicos. Neste sentido é necessário avaliar as ferramentas
disponíveis para que este armazenamento e gerenciamento sejam realizados
constantemente, de forma segura e performática, ou seja, buscando explorar os melhores
recursos disponíveis no mercado.

Quando se trata de persistência de dados, os frameworks (abstração que une


códigos comuns entre vários projetos de software provendo uma funcionalidade genérica,
auxiliando o desenvolvimento de software) se tornam necessários, e, graças à grande
diversidade desses arcabouços, é possível optar por aquele que mais atende às
necessidades do projeto.

Problema

Existe um grande vício por parte das equipes no momento de escolher o


framework mais adequado para o projeto, fazendo com que a mesma escolha um
framework o qual já foi utilizado em um projeto anterior, ou aquele que é mais comentado
nas comunidades da internet, o famoso “todo mundo usa”.

Hipótese

A análise comparativa fornecerá informações importantes, as quais mostram os valores


reais de cada um destes frameworks, suas vantagens e desvantagens , como e quando
devem ser utilizados, situações onde deve ser evitado o uso de determinados recursos
oferecidos e estatísticas de uso ao redor do mundo.
Na prática, é notável a falta de pesquisa dos líderes quando o assunto é a busca por uma
ferramenta mais adequada, os padrões estipulados muitas vezes fogem do princípio das
boas práticas, e, o comodismo em utilizar recursos já presentes em outro momento não
permite que a execução do projeto tenha um nível de qualidade superior.

Metodologia

O estudo realizado pode ser caracterizado como de natureza tecnológica, focado em


apresentar os conceitos de Banco de Dados e Mapeamento Objeto Relacional,
principalmente.

As informações presentes são resultado de observações, análise de dados obtidos através


de constatações bibliográficas e testes realizados, incluindo levantamento de hipóteses e
problemas.

Serão abordadas pesquisas bibliográficas, se utilizando de referência nomes como Java


Persistence com Hibernate (Bauer e King), JPA Eficaz (Hebert Coelho), Hibernate in
Action, entre outros.
Persistência
A persistência é definida como a capacidade que uma linguagem ou ambiente de
programação tem de permitir que os dados e objetos “sobrevivam” a execução de um
processo, para mais tarde utilizá-los em outro processo. Atualmente o conceito inclui
também algumas operações que podem ser realizadas sobre os dados persistentes, tais
como ordenação, pesquisa e gerenciamento de concorrência/integridade.

Serialização
Consiste na transformação de objetos em memória em uma seqüência de bytes que pode
ser salva e posteriormente recuperada, podendo ser considerada uma forma de
persistência simples.

Serialização de um objeto.

As funcionalidades de serialização estão disponíveis no pacote java.io. As classes


candidatas a serialização têm que obrigatoriamente implementar a interface Serializable.
Essa interface não possui métodos ou atributos e é utilizada como um marcador.

Para serializar um objeto é necessário passá-lo como parâmetro para o


método writeObject da classe ObjectOutputStream. Para recuperá-lo deve-se utilizar o
método readObject da classe ObjectInputStream. As streams de serialização possuem todo
o mecanismo para obter e ajustar o estado dos objetos e percorrer e reconstruir o conjunto
de objetos alcançáveis. Elas devem ser utilizadas em conjunto com outras streams que
façam a ligação com um dispositivo de sistema, como arquivos, sockets ou pipes, ou
juntamente com um buffer para armazenar a seqüência de bytes gerada.

Java Database Connectivity


Com a API JDBC (Java Database Connectivity), desenvolver aplicações cliente-servidoras de
banco de dados se tornou um processo mais simples, devido à maior independência de
SGBDs provida pela API.

Essa independência é atingida através dos drivers JDBC. Cada fornecedor que deseja
tornar seu SGBD acessível a partir de uma aplicação Java disponibiliza um driver JDBC.
Este driver faz toda a comunicação com o banco, encapsulando quaisquer características
particulares que o fabricante tenha implementado. Em alguns casos, pode ser necessário
inclusive que o driver implemente funcionalidades não disponíveis no SGBD.

A JDBC se encontra nos pacotes java.sql, onde está o cerne da API, e javax.sql. Entre as
classes e interfaces mais importantes podemos citar:

 Classe DriverManager, que gerencia o acesso a múltiplas fontes de dados;


 Interface Driver, que representa um driver JDBC;
 Interface Connection, que representa uma conexão com a fonte de dados;
 Interfaces Statement, PreparedStatement e CallableStatement que permitem a
execução de comandos SQL e stored procedures;
 Interface ResultSet que representa os dados obtidos do banco
 Classe Types que define os tipos de dados JDBC;
 interface DatabaseMetaData que obtém informações sobre as capacidades do
banco que são disponibilizadas pelo driver em uso.

A JDBC é baseada nos padrões X/Open SQL CLI, SQL92 e SQL99 e tem seu foco em
acesso a dados relacionais. Entretanto, a especificação não restringe seu uso, sendo
possível implementar drivers que acessem outros tipos de fontes de dados, tais como
bancos de dados objeto-relacionais (BDORs), bancos de dados orientados a objetos
(BDOOs), XML etc.

A forma mais simples de persistir objetos com JDBC é embutir chamadas SQL
diretamente nas classes de negócio da aplicação. Essa abordagem, no entanto, diminui a
reusabilidade das classes, já que elas se tornam dependentes do mecanismo de
persistência utilizado. Por exemplo, se decidirmos substituir o uso de um banco de dados
relacional por um banco de dados XML, teremos que alterar as chamadas JDBC em toda
a aplicação.
Uma forma de minimizar esse problema é criar classes para encapsular a comunicação
com o banco de dados, formando uma “camada de persistência”. A desvantagem nesse
caso é que o desenvolvedor terá que perder muito tempo na implementação dessas novas
classes, se desviando do negócio principal da aplicação.

Mapeamento Objeto-Relacional

Com um mecanismo de mapeamento objeto-relacional (MMOR) o desenvolvedor não


precisa se preocupar com chamadas JDBC ou SQL; ele apenas configura em arquivos de
metadados como as classes de negócio deverão ser armazenadas no banco (qual campo
vai armazenar qual atributo etc.) e o mecanismo de mapeamento cuida do resto. Na
maioria dos MMORs esses arquivos seguem o padrão XML.

Alguns MMORs disponibilizam ferramentas que, a partir do modelo de classes da


aplicação, geram automaticamente o esquema para o SGBD e os metadados de
mapeamento. Em alguns casos também é gerado código fonte com o esqueleto das
classes, onde a lógica de negócio pode ser inserida (ou codificada em subclasses).
Também é comum encontrar MMORs que oferecem atualização automática de objetos
persistentes modificados e carga de dados sob demanda (lazy loading).

O tipo de MMOR mais simples é o que disponibiliza classes de persistência. Uma classe
de persistência recebe um objeto (através de métodos) e cuida de armazená-lo/recuperá-
lo do banco de dados. Ela faz a leitura, em tempo de execução, dos arquivos de metadados
para identificar como o objeto deve ser salvo/lido do banco.

Outro tipo de MMOR são os pós-processadores de código. O pós-processamento adiciona


às próprias classes de negócio a funcionalidade de persistência, de forma transparente
para o desenvolvedor.

A principal vantagem dos MMORs é o acesso a dados legados em SGBDRs. Novas


aplicações podem ser desenvolvidas e executadas de forma concomitante a aplicações
legadas, permitindo a migração suave de tecnologia ou a criação de novos serviços.

A desvantagem é que em aplicações com modelos complexos os MMORs tendem a


apresentar desempenho insatisfatório. Outras deficiências comuns são a ausência de
ferramentas para evolução do modelo da aplicação e mecanismos de consulta ad hoc
pouco integrados à linguagem de programação OO.
API de Persistência Java (JPA)
A Persistência de dados é um meio para que um aplicativo persista e recupere informações
de um sistema de armazenamento não volátil. A persistência é vital para os aplicativos
corporativos por causa do acesso necessário aos bancos de dados relacionais. Os
aplicativos que forem desenvolvidos para este ambiente devem gerenciar a persistência
por si só ou usar soluções de terceiros para manipular as atualizações e recuperações do
banco de dados com persistência. O Java™ Persistence API (JPA) fornece um mecanismo
para gerenciamento de persistência e mapeamento de objeto-relacional e funções desde
as especificações do EJB 3,0.

A especificação JPA define o mapeamento relacional de objetos internamente, em


vez de depender das implementações de mapeamento específicas do fornecedor. O JPA
é baseado no modelo de programação Java que se aplica aos ambientes Java Enterprise
Edition (Java EE), mas o JPA pode funcionar dentro de um ambiente Java SE para testar
funções do aplicativo.

A JPA representa uma simplificação do modelo de programação de persistência. A


especificação JPA define explicitamente o mapeamento relacional de objetos, em vez de
depender das implementações de mapeamento específicas do fornecedor. A JPA
padroniza a importante tarefa de mapeamento relacional de objetos utilizando anotações
ou o XML para mapear objetos para uma ou mais tabelas de um banco de dados. Para
simplificar ainda mais o modelo de programação de persistência:

 A API EntityManager pode persistir, atualizar, recuperar ou remover objetos de


um banco de dados.
 A API EntityManager e os metadados de mapeamento de objeto relacional
manipulam a maioria das operações do banco de dados sem requerer que você
grave o código JDBC ou SQL para manter a persistência.

A JPA fornece uma linguagem de consulta, ampliando a linguagem de consulta EJB


independente (também conhecida como JPQL), que pode ser usada para recuperar
objetos sem gravar consultas SQL específicas para o banco de dados com o qual você
está trabalhando.
O JPA é projetado para operar tanto dentro quanto fora de um contêiner Java
Enterprise Edition (Java EE). Ao executar a JPA em um contêiner, os aplicativos podem
usar o contêiner para gerenciar o contexto de persistência. Se não houver contêiner para
gerenciar a JPA, o aplicativo deverá manipular o gerenciamento do contexto de
persistência sozinho. Os aplicativos projetados para persistência gerenciada por contêiner
não exigem muita implementação de código para tratar a persistência, mas esses
aplicativos não podem ser utilizados fora de um contêiner. Aplicativos que gerenciam sua
própria persistência podem funcionar em um ambiente de container ou em um ambiente
Java SE.

Os contêineres Java EE que suportam o modelo de programação EJB 3.x devem


suportar uma implementação de JPA, também chamada de provedor de persistência. Um
provedor de persistência JPA usa os elementos a seguir para permitir um gerenciamento
de persistência mais fácil em um ambiente do EJB 3.x:

Unidade de persistência

Define um Objeto Completo-Modelo Relacional mapeando classes Java


(entidades + estruturas de suporte) com um banco de dados relacional. O
EntityManagerFactory utiliza esses dados para criar um contexto de persistência que
possa ser acessado por meio do EntityManager.

EntityManagerFactory

Usado para criar um EntityManager para interações com o banco de dados. Os


contêineres do servidor de aplicativos normalmente fornecem essa função, mas o
EntityManagerFactory será necessário se você estiver utilizando a persistência
gerenciada pelo aplicativo JPA. Uma instância de um EntityManagerFactory representa
um contexto de Persistência.

Contexto de persistência

Define o conjunto de instâncias ativas que o aplicativo está manipulando


atualmente. É possível criar o contexto de persistência manualmente ou por meio de
injeção.
EntityManager

O gerenciador de recursos que mantém a coleção ativa de objetos de entidade


que estão sendo usados pelo aplicativo. O EntityManager manipula a interação do banco
de dados e os metadados para mapeamentos de objetos relacionais. Uma instância de
um EntityManager representa um contexto de Persistência. Um aplicativo em um
container pode obter o EntityManager através de injeção no aplicativo ou olhando-o
para cima no nome do componente Java-espaço. Se o aplicativo gerenciar sua
persistência, o EntityManager será obtido do EntityManagerFactory.

Objetos de entidade

Uma classe Java simples que representa uma linha em uma tabela de banco de
dados em sua forma mais simples. Os objetos de entidade podem ser classes concretas
ou abstratas. Elas mantêm os estados utilizando propriedades ou campos.

API de Persistência Java e Contextos de Transação Local

O WebSphere fornece contextos de transação global e local a componentes


gerenciados. Fornecendo esses contextos para componentes gerenciados e tendo
encadeamentos para componentes gerenciados de serviço, uma transação está sempre
ativa seja para um contexto de transação global (GTC) ou um contexto de transação local
(LTC).

Este processamento não tem efeito em contextos de persistência gerenciados por


aplicativo que são JPA EntityManagers adquiridos por meio de EntityManagerFactories
injetados em um aplicativo com @PersistenceUnit. Porém, esse processamento pode
afetar os Contextos de Persistência Gerenciados por Contêiner (CMTS), ou seja, os
EntityManagers JPA injetados por meio de @PersistenceContext. Os métodos da API de
JPA requerem que uma TransactionRequiredException seja lançada quando chamada
fora dos limites de um GTC e essa exceção ainda é lançada conforme o esperado. No
entanto, enquanto o LTC permanece ativo e até que um novo GTC seja iniciado ou o final
da invocação do serviço de componente seja alcançado, o contexto de persistência CMTS
permanece ativo.

As entidades que são buscadas usando localizar ou consultar por um


EntityManager de CMTS dentro dos limites de um LTC ainda são gerenciadas por esse
contexto de persistência, em vez de se tornarem imediatamente desanexadas. Como
resultado desse processamento, que pode parecer um comportamento inesperado e uma
diferença de comportamento com alguns guias de programação JPA, o contexto de
persistência que é mantido ativo pelo LTC é descartado assim que o GTC é iniciado e as
entidades gerenciadas por esse contexto de persistência se desanexar.

Frameworks de persistência

são utilizados para realizar o mapeamento de dados de aplicações desenvolvidas


no paradigma orientado a objetos para permitir seu armazenamento em bancos de dados
relacionais e por isto são também denominados frameworks de mapeamento objeto-
relacional.

Hibernate

O Hibernate é um framework de persistência de dados, seguindo o conceito de


mapeamento objeto-relacional, que visa ser uma solução eficiente e eficaz para o
problema de gerenciamento de dados persistentes em Java. (BAUER e KING, 2007).

A utilização desse framework facilita o armazenamento e recuperação de objetos


em Java com seu mapeamento objeto-relacional. Também trabalha com o modelo de
objetos POJO que segundo Shaefer e Isaia (2006), são objetos Java, sem nenhuma lógica,
contendo apenas atributos e seus respectivos métodos de acesso (getters e setters).
Tratando-se de suporte a banco de dados, oferece um suporte considerável, e, mesmo que
este não seja possível por algum motivo, existe a possiblidade da utilização de um driver
para sanar tal problema

Foi desenvolvido por uma equipe de programadores Java, tendo sua primeira
versão divulgada em 2004. Posteriormente, JBoss Inc (empresa adquirida pela Red Hat)
contratou os principais programadores para se juntar ao seu suporte. Segundo King, a
intenção de criar o projeto se deu na tentativa de resolver problemas referentes à
persistência, causados por outras ferramentas, e, considerados por ele muito complexos.
Atualmente, é encontrado como software livre para as plataformas Java e .NET, podendo
ser utilizado gratuitamente sob a licença LGPL (Lesser GPL). Só é possível estabelecer
conexões com bancos de dados relacionais, mapeando as entidades na aplicação (objetos
correspondentes às tabelas da base de dados).
Tornou-se a implementação mais utilizada para a especificação JPA (Java
Persistence API), recebendo diversas melhorias com o passar do tempo, pela própria
equipe do Hibernate, que são distribuídas na forma de plug-ins, como por exemplo
Hibernate Validator, Hibernate OGM, entre outros. Seu principal objetivo se dá em
substituir cerca de 90% das tarefas repetitivas da programação envolvendo persistência,
evitando que eles gerem códigos SQL manualmente.

A partir da versão 3.5, foi declarado como uma implementação certificada para a
especificação JPA2 (JSR 317), que se consagrou oficial em 2009. Com a evolução da
ferramenta, surgiram novos recursos e muitos dos existentes foram aprimorados. A
decisão de utilizar o Hibernate ao invés de outros frameworks envolve vários fatores,
mas, principalmente pelo fato de ser o framework ORM mais presente no mercado e
implementar a especificação Java EE para persistência, o JPA.

MyBatis

MyBatis é um framework open source de persistência de dados, desenvolvido em


2002 por Clinton Begin, e tem como objetivo simplificar a implementação da camada de
persistência, abstraindo códigos JDBC e oferece uma API simples e de fácil interação
com bancos de dados, podendo ser uma alternativa tanto ao JDBC quanto ao Hibernate.

Era conhecido como iBatis, sob licença da Apache, e após esse período, migrou para o
Google Code, onde teve seu nome alterado para MyBatis, porém, manteve a configuração
(exceto pelo schema dos arquivos de configuração).

Dispõe de uma performance otimizada, como suporte à pool de conexões (que


impedem a criação de uma nova conexão à cada requisição) e mecanismo de cache para
consultas. Oferece suporte à SQL customizado, stored procedures, mapeamento avançado
e integração com frameworks como Spring, Guice, e bibliotecas de cache de terceiros
(mesmo possuindo suporte para cache embutido).

Pode ser configurado através de annotations ou XML e tem boa integração com
bancos de dados legados, o que é um diferencial interessante, pois a dificuldade de se
trabalhar com bancos legados utilizando, por exemplo, frameworks ORM, é muito
grande, devido ao mapeamento entre a base de dados e os objetos da aplicação.

Dentre as principais razões da popularidade do MyBatis, uma delas se trata da


simplicidade de aprendizagem e uso, tornando-se ainda mais simples caso o
desenvolvedor tenha conhecimento de Java e SQL. Fornece também gerenciamento de
transações para operações no banco de dados, porém, caso houver outro gerenciador
disponível, delegará o gerenciamento à este.

Configuração

A configuração dos frameworks foi realizada por arquivos XML, mais


especificamente, “sqlmapconfig.xml” (MyBatis) e hibernate.cfg.xml (Hibernate). As
configurações envolvem: o endereço de acesso ao banco de dados, o dialeto ao ser
utilizado (MySQL, neste caso), usuário e senha, entre outras configurações como é
possível visualizar nas imagens abaixo:

Configuração realizada no arquivo hibernate.cfg.xml para funcionamento do framework Hibernate

Configuração realizada no arquivo sqlmapconfig.xml para funcionamento do framework MyBatis.


Consultas
Neste tópico foram abordadas as operações de consulta ao banco de dados (selects). Uma
consulta pode ser simples, retornando, por exemplo, todos os registros e todos os campos
da tabela Empregados, utilizando o seguinte comando:

SELECT * FROM Empregados;


A consulta pode se tornar complexa conforme a query se estende, adicionando
selects internos, funções variadas (soma, média, substituição) e joins (junções) com outras
tabelas, como é o caso do segundo exemplo de consulta realizado:

SELECT (e.salary-1000), AVG(e.salary), REPLACE(e.full_name, 'a', 'o')

FROM employees e INNER JOIN department d ON e.department_id = d.department_id


INNER JOIN job j ON d.department_id = j.department_id

WHERE e.full_name like 'A%'

AND e.age BETWEEN 30 AND 45

AND d.department_name LIKE '%a%'

AND j.job_title LIKE '%a%'

AND j.max_salary <= 25000;


O resultado obtido na primeira execução (consulta de 10.000 registros utilizando
o primeiro exemplo de comando citado), levando em conta o tempo de execução, foi de
0.7 segundos para o MyBatis e de 1.6 segundos para o Hibernate.

Na segunda execução, o tempo de execução foi de 0.01 segundos para o Hibernate


e 0.06 segundos para o MyBatis. Se observarmos a diferença de tempo entre a primeira e
a segunda execução, o Hibernate teve uma melhor performance, e, isso acontece devido
ao recurso de cache, onde os registros retornados na primeira consulta permanecem em
memória, e, ao identificar que o comando executado é o mesmo, ocorre apenas uma
consulta à estes registros na memória, e não mais no banco de dados. De acordo com as
estatísticas, o Hibernate fez um melhor trabalho ao utilizar o recurso de cache.
Já no segundo exemplo de comando citado, o framework Hibernate atingiu um tempo de
execução de 1.3 segundos, contra 0.2 segundos do concorrente MyBatis. Na segunda
execução, a ferramenta ORM atingiu 0.001 segundos, contra 0.06 segundos do MyBatis.

É notável o ganho de performance do Hibernate quando se trata da tecnologia de


cache, porém, quando uma aplicação tem a necessidade de executar comandos diferentes
constantemente, não é possível utilizar os benefícios do cache, pois a consulta deve ser
realizada diretamente no banco de dados, e, para ambos os cenários de consulta, o
MyBatis demonstrou melhor desempenho nas primeiras execuções dos comandos.

Inserções
Foram realizadas operações de inserção simples, inserindo 1000 registros em
ambos os casos, com todos os campos vazios. Para o Hibernate foi utilizado o método
save de sua própria API, o qual executa um insert implicitamente, como é possível
visualizar abaixo:

Código do método responsável por inserir 1000 registros na base utilizando o Hibernate

Para o MyBatis foi utilizado o comando INSERT, o qual foi mapeado no arquivo
Employee.xml, onde devem ficar todos os comandos referentes à esta entidade (selects,
updates, inserts e deletes), no caso, Employee:

Código INSERT mapeado no arquivo Employee.xml (arquivo de configuração de comandos SQL referentes à entidade Employee).
O resultado obtido na primeira execução (inserção de 1.000 registros) para o Hibernate
foi de 0.8 segundos, e, para o MyBatis, 1.1 segundos. Na segunda execução (utilizando
exatamente os mesmos comandos), o Hibernate atingiu 0.7 segundos e o MyBatis
alcançou 0.8 segundos.

Ao analisar estes resultados, pode-se notar que a primeira inserção tem um tempo
maior em ambos os casos, porém, o Hibernate teve melhor desempenho nas duas
execuções, mesmo sendo perceptível uma evolução maior do MyBatis entre a

primeira e segunda execução.

Não foram abordadas as operações de alteração e remoção, pois seguem o mesmo


conceito da inserção, persistência, enquanto a consulta engloba um cenário diferente, o
retorno de registros presentes na base de dados.

Vantagens

 Programadores no precisam conhecer nada a respeito do esquema do BD


relacional.
 Permite desenvolvimento de aplicaıes em larga escala.

Desvantagens

 Impacto no desempenho das aplicaıes.


 Propicia degeneralização conceitual com impacto negativo no modelo de banco
de dados.
Conclusão
REFERENCIAS BIBLIOGRAFICAS

Você também pode gostar