Os aplicativos corporativos geralmente lidam com operações como coleta, processamento, transformação e geração de relatórios de uma grande quantidade de dados. Esses dados são normalmente armazenados em um servidor de banco de dados em um local específico e recuperados sob demanda. A aplicação é responsável por processar os dados do banco de dados e por fim apresentá-los para consumo do cliente. Mas, os meandros envolvidos em mitigar a troca de dados entre diferentes arquiteturas é o verdadeiro desafio que os desenvolvedores enfrentam. O cerne do problema está em facilitar a complicada relação de movimentação de dados entre o código usado para desenvolver o aplicativo e o modelo de armazenamento usado para a persistência de dados. Em suma, a ideia é criar um mecanismo de interação perfeita entre dois modelos inflexíveis:a natureza orientada a objetos da linguagem Java e o modelo de banco de dados relacional.
APIs básicas para bancos de dados
A plataforma Java já possui APIs padrão para trabalhar com sistemas de banco de dados na forma de APIs JDBC. Essas APIs são excelentes para trabalhar com o banco de dados e fornecem os meios necessários para interagir convenientemente com o banco de dados a partir da linguagem Java. Mas, o problema é que Java é uma linguagem orientada a objetos. O JDBC fornece APIs principais para interação com o banco de dados e não se concentra em transformar a estrutura de linha e coluna da tabela de banco de dados em uma classe de entidade. Portanto, busca-se uma camada de API que funcione acima da API JDBC. A API de persistência, ou JPA, mitiga dois modelos arquiteturalmente diferentes com o objetivo de alavancar a fluidez da operação. A API ajuda a representar uma tabela de relação de banco de dados como um POJO e pode ser tratada de maneira semelhante em todo o código Java. A API central do JDBC funciona em segundo plano para lidar com os meandros da comunicação e da conexão com o banco de dados, enquanto o JPA permite que as negociações sejam feitas de acordo com o código orientado a objetos da linguagem Java. No entanto, o mapeamento de dados entre banco de dados relacional e Java não é uma tarefa fácil.
Suporte de persistência Java
Em um banco de dados relacional típico, as informações são armazenadas em uma estrutura de linha e coluna. A troca de dados entre um sistema de banco de dados e o modelo de objeto do aplicativo Java é difícil porque Java designa uma única entidade como uma classe denotada por um conjunto de propriedades e operações aplicadas nelas. Portanto, para conformar uma incompatibilidade comportamental entre as duas arquiteturas diferentes, um programador Java precisa escrever muitas linhas de código. Essas linhas de código ajudam a transformar os dados de linha e coluna da tabela de banco de dados em objetos Java. Mas, muitas vezes, essas linhas de código se tornam muito repetitivas, resultando no código-fonte repleto de códigos clichê. Isso é indesejável e viola o princípio básico de reutilização orientado a objetos. Embora códigos inteligentes possam mitigar muitas das adversidades, não é uma solução fácil. O surgimento de soluções de terceiros é uma pausa no mapeamento de dados de banco de dados em objetos Java, mas eles não eram padrão. Cada implementação de fornecedor variou consideravelmente de outra. Isso tudo significa que a situação exigia uma biblioteca de API de persistência padrão da própria plataforma Java. Isso levou à introdução da Java Persistence API (JPA), especialmente para preencher a lacuna entre o modelo de domínio orientado a objetos de Java e o sistema de banco de dados.
Soluções proprietárias
Entenda que as soluções objeto-relacionais já existem há algum tempo, antes mesmo do nascimento da própria linguagem Java. Por exemplo, o produto TopLink da Oracle realmente começou com Smalltalk e depois mudou para Java. Hoje, faz parte dos servidores OracleAS, WebLogic e OC4J. Na verdade, as duas APIs de persistência mais populares costumavam ser o TopLink da Oracle, um padrão proprietário no domínio comercial, e o Hibernate no domínio da comunidade de código aberto. Mais tarde, o Hibernate tornou-se mais popular e influenciou fortemente a criação da biblioteca JPA padrão.
Mapeadores de dados
Um mapeador de dados é basicamente um padrão de arquitetura proposto por Martin Fowler em seu livro Patterns of Enterprise Application Architecture , 2003. Ele fornece uma maneira parcial de abordar o problema relacional de objeto. O mapeador ajuda a criar uma estratégia que se enquadra na categoria entre JDBC simples e uma solução de mapeamento relacional de objeto totalmente funcional. Aqui, os desenvolvedores de aplicativos criam uma string SQL bruta para mapear tabelas de banco de dados para objetos Java usando o método mapeador de dados. Existe um framework popular que utiliza essa técnica de mapeamento entre banco de dados SQL e objeto Java, chamado Apache iBatis. O projeto Apache iBatis foi declarado inativo agora. No entanto, os criadores originais do Apache iBatis transferiram o projeto para o MyBatis e está em desenvolvimento ativo.
Ao contrário de outras soluções de problemas relacionais de objetos usando a estrutura de mapeadores de dados como MyBatis, podemos ter controle total sobre as transações SQL com o banco de dados. É uma solução leve e não carrega a sobrecarga de uma estrutura ORM completa. Mas há um problema com os mapeadores de dados. Quaisquer alterações feitas no modelo de objeto têm repercussões no modelo de dados. É preciso fazer alterações significativas nas instruções SQL diretamente como consequência. A natureza minimalista do framework ajuda os desenvolvedores a incorporar novas mudanças e modificações de acordo com a necessidade. Os mapeadores de dados são particularmente úteis em uma situação em que precisamos de uma estrutura mínima, manipulação de SQL explícita e mais controle para modificação do desenvolvedor.
JDBC
O JDBC (Java Database Connectivity) é uma versão específica do Java da especificação ODBC (Object Database Connectivity) da Microsoft. O ODBC é um padrão para conectar qualquer banco de dados relacional de qualquer linguagem ou plataforma. O JDBC fornece abstração semelhante em relação à linguagem Java. JDBC usa SQL para interagir com o banco de dados. Os desenvolvedores devem escrever consultas DDL ou DML de acordo com a especificação sintática do banco de dados backend, mas processá-las usando o modelo de programação Java. Há um forte acoplamento entre a origem Java e as instruções SQL. Podemos recorrer a instruções SQL brutas e manipulá-las estaticamente de acordo com a necessidade. Devido à sua natureza estática, é difícil incorporar mudanças. Além disso, os dialetos SQL variam de um fornecedor de banco de dados para outro. O JDBC é conectado ao banco de dados e não ao modelo de objeto da linguagem Java. Portanto, logo parece complicado trabalhar com ele, especialmente quando a interação do banco de dados do código-fonte Java aumenta. No entanto, JDBC é o principal suporte para persistência de banco de dados em Java e forma a base para estruturas de alto nível.
EJB
O Enterprise Java Bean (EJB) com J2EE trouxe algumas novas mudanças na arena de persistência Java na forma do bean de entidade. A ideia era isolar os desenvolvedores de intervir diretamente nos meandros da persistência do banco de dados. Ele introduziu uma abordagem baseada em interface. Existe um compilador de bean especializado para gerar a implementação para persistência, gerenciamento de transações e delegação de lógica de negócios. Descritores de implantação XML especializados foram usados para configurar os beans de entidade. O problema é que o EJB, ao invés de simplificar as coisas, incorporou muita complexidade. Como resultado, apesar das inúmeras melhorias subsequentes, como a introdução da Enterprise JavaBeans Query Language (EJB QL), ela logo perdeu popularidade.
Objeto de dados Java
O JDO (Java Data Object) tentou resolver o problema enfrentado pelo modelo de persistência EJB. Ele fornece uma API para persistência transparente e foi projetado para funcionar com EJB e J2EE. JDO é um produto fortemente influenciado e suportado por bancos de dados orientados a objetos. Objetos de persistência são objetos Java simples que não requerem que um desenvolvedor implemente nenhuma classe ou interface especial. Especificações de persistência de objeto são normalmente definidas em um metarquivo XML. As linguagens de consulta suportadas são orientadas a objetos por natureza. Apesar de muitos bons recursos, a especificação JDO não conseguiu muita aceitação entre a comunidade de desenvolvedores.
API de persistência Java
Havia uma série de estruturas de persistência proprietárias tanto no domínio comercial quanto no domínio de código aberto. Frameworks como Hibernate e TopLink pareciam atender muito bem às necessidades da aplicação. Como resultado, o Hibernate foi escolhido como base primária para a criação de um modelo de persistência padrão chamado JPA.
JPA é uma estrutura leve padrão de persistência Java que ajuda a criar mapeamento relacional de objetos usando POJO. A JPA também ajuda a integrar a persistência em um aplicativo corporativo escalável. É fácil de usar porque há apenas um pequeno número de classes que precisam ser expostas a um aplicativo interessado em usar o modelo de persistência JPA. O uso de um POJO é talvez o aspecto mais intrigante do JPA. Significa que não há nada de especial no objeto; que o torna persistente. O mapeamento objeto-relacional é orientado por metadados. Isso pode ser feito usando anotação internamente no código ou externamente. usando XML.
As APIs persistentes do JPA existem como uma camada separada do objeto persistente. A lógica de negócios normalmente invoca a API e passa o objeto persistente para operar sobre eles. Embora o aplicativo esteja ciente da API persistente, o objeto persistente, sendo POJO, desconhece completamente sua capacidade de persistência.
Conclusão
Este artigo forneceu uma visão geral de algumas das soluções proprietárias disponíveis antes da introdução do JPA, como mapeador de dados, JDBC e EJB. A ideia é dar uma ideia do que levou à criação do JPA, e um pouco sobre a técnica persistente de seu antecessor. Fique atento; artigos subsequentes se aprofundam em aspectos mais específicos da API JPA.