Quando as pessoas são novas para JPA, Hibernate ou EclipseLink, eles são muitas vezes confusos sobre a diferença entre elas e qual a que deve usar no seu projeto. Se és um deles, não te preocupes. É muito mais fácil do que parece.
Let’s take a look at the JPA specification first.
Java Persistence API (JPA)
JPA é uma abreviatura que significa Java Persistence API. É uma especificação que faz parte do Java EE e define uma API para mapeamentos objeto-relacional e para a gestão de objetos persistentes. Você pode usar esta API em ambientes Java SE e Java EE.
A especificação está actualmente disponível na versão 2.2. Você pode baixar o documento em https://jcp.org/en/jsr/detail?id=338. O jar API está disponível nas seguintes coordenadas Maven:
<dependency> <groupId>javax.persistence</groupId> <artifactId>javax.persistence-api</artifactId> <version>2.2</version></dependency>
app em si não fornece quaisquer classes de implementação. O jar API apenas contém um conjunto de interfaces que você pode usar para implementar a sua camada de persistência. Mas não podes usar a App sozinha. Você precisa de um provedor de JPA que implementa a especificação. Existem várias opções disponíveis. Os mais populares são hibernados e EclipseLink. Mas mais sobre isso mais tarde.
até recentemente, a App foi gerenciada e desenvolvida por um grupo de especialistas seguindo o processo comunitário Java (JCP). Isso mudou quando a Oracle anunciou transferir todas as especificações Java EE para a Eclipse Foundation. Estamos agora no meio do processo de transição, e um novo processo de especificação será definido em breve.
o que é definido pela especificação da App
a especificação define a maioria das características que eu expliquei nos tutoriais e vídeos neste site. Você pode usá-los com todas as implementações compatíveis da App.
vamos dar uma olhada em alguns dos mais importantes.
Bootstrapping e mapeamentos básicos de entidades
Antes de poder começar a usar o JPA, você precisa adicioná-lo ao seu projecto, configurar uma unidade de persistência, mapear entidades para as suas tabelas de base de dados e iniciá-lo. Você provavelmente já sabe como fazer isso, e eu expliquei isso em grande detalhe em meu começo com Artigo hibernado.então, vamos saltar esta parte aqui e falar sobre as características mais interessantes.
associações de mapeamento
app não só lhe permite mapear atributos de entidades simples para colunas de bases de dados, como também lhe permite mapear associações entre tabelas de bases de dados para atributos de entidades.
@Entitypublic class Review {...@ManyToOneprivate Book book;...}
Que muitas vezes torna o seu modelo de entidade muito confortável de usar, porque você só precisa chamar um método getter em uma entidade para carregar as entidades associadas. No fundo, o provedor persistência realiza todas as operações de banco de dados necessárias para recuperar e gerenciar a associação.
tão confortável de usar como este pode ser, Esta característica muitas vezes causa problemas de desempenho. Antes de começar a modelar as associações entre as suas entidades, certifique-se que compreende o efeito dos FetchTypes da JPA para evitar problemas de selecção n+1.
JPQL e consultas nativas
JPA define a sua própria linguagem de consulta, chamada JPQL. É semelhante ao SQL, mas permite definir consultas com base no modelo de domínio mapeado em vez do modelo de tabela do banco de dados.
o seguinte excerto de código mostra uma consulta JPQL simples. Você pode definir uma consulta ad-hoc chamando o método createQuery no EntityManager em. Como você pode ver, a sintaxe parece muito semelhante ao SQL. Se você não está familiarizado com JPQL, por favor, dê uma olhada no meu guia JPQL no qual eu explico sua sintaxe e capacidades em grandes detalhes.
TypedQuery<Book> q = em.createQuery("SELECT b FROM Book b WHERE b.id = :id", Book.class);q.setParameter("id", 1L);Book b = q.getSingleResult();
quando executa tal consulta, o seu fornecedor de persistência interpreta a declaração JPQL e gera uma consulta SQL para ela. Ao fazer isso, o provedor persistência adapta a consulta ao dialeto SQL específico do banco de dados e melhora a portabilidade de sua aplicação.
infelizmente, isso também o limita às funcionalidades de consulta definidas pela especificação ou suportadas pelo seu fornecedor de persistência. Este conjunto de recursos é significativamente menor do que o oferecido pelo SQL e não inclui quaisquer recursos de banco de dados proprietários.
mas isso não significa que você não pode usar quaisquer consultas avançadas ou complexas com JPA. Ele é projetado como uma abstração vazante e permite que você execute consultas nativas SQL. Estes não são analisados pelo seu provedor persistência, e você pode usar todas as funcionalidades suportadas pelo seu banco de dados. Mas, por favor, esteja ciente de que isso pode afetar negativamente a portabilidade do seu banco de dados.
executar uma consulta nativa é bastante simples. Você só precisa chamar o método createNativeQuery em vez do método createQuery em seu EntityManager com uma consulta SQL nativa.
Query q = em.createNativeQuery("SELECT * FROM book b WHERE id = :id", Book.class);q.setParameter("id", 1L);Book b = (Book) q.getSingleResult();
tipos de Dados Personalizados
a especificação App define o mapeamento para a maioria dos tipos-padrão sem o limitar a eles. Desde a JPA 2.1, você pode facilmente suportar tipos de dados personalizados com um AttributeConverter. Você só precisa implementar a interface AttributeConverter e anotar a classe com uma anotação @Converter.
Aqui está um exemplo de um conversor de atributos que define um mapeamento personalizado para o meu enum AuthorStatus.
@Converter(autoApply = true)public class AuthorStatusConverter implements AttributeConverter<AuthorStatus, String> {Logger log = Logger.getLogger(AuthorStatusConverter.class.getSimpleName());@Overridepublic String convertToDatabaseColumn(AuthorStatus status) {switch (status) {case NOT_PUBLISHED:logDbConversion(status, "N");return "N";case PUBLISHED:logDbConversion(status, "P");return "P";case SELF_PUBLISHED:logDbConversion(status, "S");return "S";default:throw new IllegalArgumentException("AuthorStatus not supported.");}}@Overridepublic AuthorStatus convertToEntityAttribute(String dbData) {switch (dbData) {case "N":logEntityConversion(AuthorStatus.NOT_PUBLISHED, "N");return AuthorStatus.NOT_PUBLISHED;case "P":logEntityConversion(AuthorStatus.PUBLISHED, "P");return AuthorStatus.PUBLISHED;case "S":logEntityConversion(AuthorStatus.SELF_PUBLISHED, "S");return AuthorStatus.SELF_PUBLISHED;default:throw new IllegalArgumentException("AuthorStatus not supported.");}}private void logDbConversion(AuthorStatus status, String dbData) {log.debug("Convert AuthorStatus enum to .");}private void logEntityConversion(AuthorStatus status, String dbData) {log.debug("Convert DB value to AuthorStatus enum .");}}
EclipseLink e hibernar
como eu disse antes, você precisa de um provedor JPA, se você quiser usar a especificação JPA no seu projeto. Implementa as interfaces definidas pela especificação. Os mais populares são o EclipseLink e o Hibernate.
uma vantagem da API padronizada fornecida pela APP é que você só precisa adicionar sua implementação em tempo de execução e que você pode substituí-la por uma diferente sem alterar qualquer código. A API padronizada faz EclipseLink e hibernar intercambiáveis.
então, por que você precisa de diferentes implementações?
as implementações da App são gerenciadas por equipes independentes, e você pode escolher a que fornece o melhor desempenho ou suporte para a sua aplicação e pilha de tecnologia. Eles também se diferenciam fornecendo funcionalidades adicionais e não-padrão. Isto é muitas vezes usado para impulsionar a inovação. O recurso popular e proprietário de hoje pode ser o primeiro passo para a próxima adição ao padrão da App. Usando qualquer uma dessas características proprietárias, obviamente, torna muito mais difícil substituir uma implementação específica da App.
EclipseLink
EclipseLink é a implementação de referência da JPA e implementa a versão 2.2 da JPA. Foi um dos primeiros projetos que se tornou parte do EE4J.
a maneira mais fácil de adicionar EclipseLink ao seu projeto é usar as seguintes coordenadas Maven.
<dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.7.1</version></dependency>
características proprietárias interessantes
além das características definidas pela norma DA APP, a EclipseLink também oferece várias características interessantes, como::
- Manipulação de banco de dados de eventos de alteração
- Composto de persistência unidades para mapear entidades para tabelas em várias bases de dados
- Suporte para multi-tenancy
Hibernate
o Hibernate a Red Hat está muito populares implementação da especificação JPA. Ele implementa quase todos os recursos definidos pela JPA 2.2 e irá lançar uma versão totalmente compatível em breve.
a seguinte dependência de Maven adiciona hibernar ao seu projecto.
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.1.11</version></dependency>
Interessante recursos próprios
Semelhante para EclipseLink, o Hibernate fornece um monte de interessante, recursos próprios, como:
- suporte Estendido para a natural IDs
- Carregamento de várias entidades pela sua chave primária
- Gerenciamento de criação e atualização de carimbos de data / hora
- Aderir a não associados a entidades de consultas
- Suporte para multi-tenancy