Como uma especificação, o Java Persistence API está preocupado com a persistência, que vagamente significa qualquer mecanismo pelo qual os objetos de Java sobreviver o processo de aplicação que os criou. Nem todos os objetos Java precisam ser persistidos, mas a maioria das aplicações persistem objetos de Negócio chave. A especificação da JPA permite definir quais objetos devem ser persistidos, e como esses objetos devem ser persistidos em suas aplicações Java.por si só, a APP não é uma ferramenta ou uma estrutura; em vez disso, define um conjunto de conceitos que podem ser implementados por qualquer ferramenta ou framework. Enquanto o modelo de mapeamento objeto-relacional da JPA (ORM) foi originalmente baseado no hibernado, ele evoluiu desde então. Da mesma forma, enquanto a JPA foi originalmente destinada a ser usada com bases de dados relacionais/SQL, algumas implementações da JPA foram estendidas para uso com datastores de NoSQL. Uma estrutura popular que suporta a APP com a NoSQL é a EclipseLink, a implementação de referência para a App 2.2.
JPA e Hibernato
devido à sua história entrelaçada, Hibernato e JPA são frequentemente confundidos. No entanto, como a especificação servlet Java, a JPA gerou muitas ferramentas e frameworks compatíveis; Hibernate é apenas uma delas.
desenvolvido por Gavin King e lançado no início de 2002, Hibernate é uma biblioteca ORM para Java. King desenvolveu Hibernato como uma alternativa aos feijões entity para persistência. O quadro era tão popular, e tão necessário na época, que muitas de suas ideias foram adotadas e codificadas na primeira especificação da App.
hoje, hibernar ORM é uma das implementações JPA mais maduras, e ainda uma opção popular para ORM em Java. Hibernar ORM 5.3.8 (a versão atual desta escrita) implementa a JPA 2.2. Além disso, a família de ferramentas do Hibernate expandiu-se para incluir ferramentas populares como o Hibernate Search, o Hibernate Validator e o Hibernate OGM, que suporta persistência de modelos de domínio para NoSQL.
o que é Java ORM?
apesar de diferirem na execução, cada implementação da App fornece algum tipo de camada ORM. Para compreender as ferramentas compatíveis com a APP e a App, é necessário ter uma boa compreensão da ORM.o mapeamento objeto-relacional é uma tarefa-tarefa que os desenvolvedores têm boas razões para evitar fazer manualmente. Um framework como Hibernate ORM ou EclipseLink codifica essa tarefa em uma biblioteca ou framework, uma camada ORM. Como parte da arquitetura de Aplicação, A camada ORM é responsável por gerenciar a conversão de objetos de software para interagir com as tabelas e colunas em um banco de dados relacional. Em Java, a camada ORM converte classes e objetos Java para que possam ser armazenados e gerenciados em um banco de dados relacional.
Por padrão, o nome do objeto que persiste torna-se o nome da tabela, e os campos tornam-se colunas. Uma vez que a tabela é configurada, cada linha da tabela corresponde a um objeto na aplicação. O mapeamento de objetos é configurável, mas os valores por omissão tendem a funcionar bem.a Figura 1 ilustra o papel da APP e da camada ORM no desenvolvimento de aplicações.
configurar a camada ORM Java
quando configurar um novo projecto para usar a JPA, terá de configurar o fornecedor de dados e da JPA. Irá configurar um conector datastore para se ligar à sua base de dados escolhida (SQL ou NoSQL). Você também irá incluir e configurar o provedor de JPA, que é uma estrutura como hibernar ou EclipseLink. Embora possa configurar manualmente a JPA, muitos programadores optam por usar o suporte fora-da-caixa da Primavera. Veja abaixo “JPA installation and setup” para uma demonstração da instalação e configuração manual e com base em molas da JPA.
persistência dos dados em Java
de uma perspectiva de programação, a camada ORM é uma camada adaptadora: adapta a linguagem dos grafos objeto à linguagem de tabelas SQL e relacionais. A camada ORM permite que desenvolvedores orientados a objetos construam software que persiste dados sem nunca deixar o paradigma orientado a objetos.
Quando você usa JPA, você cria um mapa do datastore para os objetos do modelo de dados da sua aplicação. Em vez de definir como os objetos são salvos e recuperados, você define o mapeamento entre os objetos e seu banco de dados, em seguida, invocar a JPA para persisti-los. Se você estiver usando um banco de dados relacional, grande parte da conexão real entre seu código de aplicação e o banco de dados será então tratada pelo JDBC, a API de conectividade de banco de dados Java.
Como uma spec, a App fornece anotações de meta-dados, que você usa para definir o mapeamento entre objetos e a base de dados. Cada implementação da App fornece seu próprio motor para anotações da App. A spec da JPA também fornece o PersistanceManager
ou EntityManager
, que são os principais pontos de contato com o sistema JPA (onde o seu código lógico de negócios diz ao sistema o que fazer com os objetos mapeados).
para tornar tudo isso mais concreto, considere listar 1, que é uma classe de dados simples para modelar um músico.Lista 1. Para armazenar dados, é utilizada uma classe de dados simples em Java
o Musician
classe na lista 1. Pode conter dados primitivos como o campo Nome. Ele também pode manter relações com outras classes como mainInstrument
eperformances
.
Musician
a razão de ser é conter dados. Este tipo de classe é às vezes conhecido como um DTO, ou objeto de transferência de dados. DTOs são uma característica comum do desenvolvimento de software. Enquanto eles possuem muitos tipos de dados, eles não contêm qualquer lógica de negócios. Objetos de dados persistentes é um desafio onipresente no desenvolvimento de software.
persistência dos dados com JDBC
uma maneira de salvar uma instância doMusician
Classe A uma base de dados relacional seria usar a biblioteca JDBC. JDBC é uma camada de abstração que permite a uma aplicação emitir comandos SQL sem pensar sobre a implementação de banco de dados subjacente.
Listagem 2 mostra como é possível persistir a classeMusician
utilizando a classe JDBC.
Listagem 2. JDBC inserindo um registro
o código na lista 2 é bastante auto-documentado. The georgeHarrison
object could come from anywhere (front-end submit, external service, etc.), e tem seus campos de ID e nome definidos. Os campos no objeto são então usados para fornecer os valores de uma declaração SQL insert
. (The PreparedStatement
class is part of JDBC, offering a way to Safety apply values to an SQL query.)
enquanto JDBC permite o controle que vem com a configuração manual, é complicado em comparação com a JPA. A fim de modificar o banco de dados, você primeiro precisa criar uma consulta SQL que mapeia de seu objeto Java para as tabelas em um banco de dados relacional. Você então tem que modificar o SQL sempre que uma assinatura de objeto muda. Com o JDBC, manter o SQL torna-se uma tarefa em si.
persistência dos dados com a App
considere agora a Listagem 3, onde persistimos oMusician
classe utilizando app.
Listagem 3. Persisting George Harrison with JPA
Musician georgeHarrison = new Musician(0, "George Harrison");musicianManager.save(georgeHarrison);
Listing 3 replaces the manual SQL from Listing 2 with a single line, session.save()
, which instructions JPA to persist the object. A partir daí, a conversão SQL é tratada pelo framework, então você nunca tem que deixar o paradigma orientado a objetos.
anotações de metadados em JPA
a magia na lista 3 é o resultado de uma configuração, que é criada usando as anotações da JPA. Os desenvolvedores usam anotações para informar a JPA quais objetos devem ser persistidos, e como eles devem ser persistidos.
Listing 4 shows the Musician
class with a single JPA annotation.
Listagem 4. @ Entity annotation
@Entitypublic class Musician { // ..class body}
Persistent objects are sometimes called entities. Anexar @Entity
a uma classe como Musician
informa a JPA de que esta classe e os seus objectos devem ser mantidos.
configurar a JPA
como a maioria dos frameworks modernos, a JPA abrange codificação por convenção (também conhecida como Convenção sobre configuração), na qual a framework fornece uma configuração padrão baseada nas melhores práticas da indústria. Como um exemplo, uma classe chamada Musician
seria mapeada por padrão para uma tabela de banco de dados chamada Musician.
a configuração convencional é um preservador de tempo, e em muitos casos funciona bem o suficiente. Também é possível personalizar a sua configuração JPA. Como exemplo, você pode usar a anotação
para especificar a tabela onde a classeMusician
deve ser armazenada.
Listagem 5. A anotação da tabela @app
@Entity@Table(name="musician")public class Musician { // ..class body}
Listagem 5 diz à App para persistir a entidade (Musician
classe) na tabela musician
.
chave primária
na App, a chave primária é o campo usado para identificar de forma única cada objeto na base de dados. A chave primária é útil para referenciar e relacionar objetos com outras entidades. Sempre que você armazenar um objeto em uma tabela, você também irá especificar o campo a usar como sua chave primária.
na lista 6, dizemos à App qual o campo a utilizar como Musician
‘s chave primária.
Listagem 6. Especificar a chave primária
@Entitypublic class Musician { @Id private Long id;
neste caso, temos usado o APP da @Id
anotação para especificar o id
campo Musician
‘s de chave primária. Por padrão, esta configuração assume que a chave primária será definida pela base de dados–por exemplo, quando o campo for configurado para auto-incremento na tabela.
App suporta outras estratégias para gerar a chave primária de um objeto. Ele também tem anotações para mudar nomes de campos individuais. Em geral, a App é flexível o suficiente para se adaptar a qualquer mapeamento de persistência que você possa precisar.
operações CRUD
Uma vez mapeada uma classe para uma tabela de banco de dados e estabelecida a sua chave primária, você tem tudo o que precisa para criar, recuperar, apagar e atualizar essa classe na base de dados. Invocando session.save()
criará ou actualizará a classe especificada, dependendo se o campo da chave primária é nulo ou se aplica à en entidade existente. Chamando entityManager.remove()
irá apagar a classe especificada.
Entity relationships in JPA
Simply persisting an object with a primitive field is only half the equation. A APP também tem a capacidade de gerenciar entidades em relação umas às outras. Quatro tipos de relações de entidade são possíveis em ambas as tabelas e objetos:
- Um-para-muitos
- Muitos-para-um
- Muitos-para-muitos
- Um-para-um
Cada tipo de relação que se descreve como uma entidade relaciona-se com outras entidades. Por exemplo, o Musician
entidade poderia ter um um-para-muitos relacionamento com Performance
, uma entidade representada por um conjunto como o List
ou Set
.
Se Musician
incluída uma Band
campo, a relação entre estas entidades podem ser muitos-para-um, o que implica coleção de Musician
s em um único Band
classe. (Assumindo que cada músico só toca em uma única banda.)
Se Musician
incluída uma BandMates
campo, que poderia representar uma relação muitos-para-muitos relacionamento com outros Musician
entidades.
Finalmente, Musician
pode ter um um-para-um relacionamento com uma Quote
entidade, usado para representar uma famosa citação: Quote famousQuote = new Quote()
.
definir tipos de relações
app tem anotações para cada um dos seus tipos de mapeamento de relações. A listagem 7 mostra como você pode anotar o um-para-muitos relacionamento entre Musician
e Performance
s.
Listagem 7. Anotar uma relação de um para muitos
uma coisa a notar é que o@JoinColumn
diz à App que coluna na tabela desempenho irá mapear para a entidadeMusician
. Cada desempenho será associado a um único Musician
, que é seguido por esta coluna. Quando a JPA carrega um Musician
ou um Performance
na base de dados, utilizará esta informação para reconstituir o gráfico do objecto.
a obter estratégias na JPA
para além de saber onde colocar as entidades relacionadas na base de dados, a JPA precisa de saber como as deseja carregadas. A obtenção de estratégias diz à JPA como carregar as entidades relacionadas. Ao carregar e salvar objetos, um framework JPA deve fornecer a capacidade de finetune como os grafos de objetos são tratados. Por exemplo, se a classeMusician
tem uma bandMate
campo (como mostrado na lista 7), carregar george
pode fazer com que toda a tabela de músicos seja carregada a partir da base de dados!
O que é necessário é a capacidade de definir o carregamento preguiçoso de entidades relacionadas–reconhecendo, é claro, que as relações na App podem ser ansiosas ou preguiçosas. Você pode usar anotações para personalizar suas estratégias de busca, mas JPA configuração padrão, muitas vezes, funciona fora da caixa, sem alterações:
- Um-para-muitos: Lazy
- Muitos-para-um: Ansioso
- Muitos-para-muitos: Lazy
- Um-para-um: Ansioso
JPA instalação e configuração
Nós vamos concluir com um rápido olhar para a instalação e configuração do JPA para as aplicações Java. Para esta demonstração vou usar a EclipseLink, a implementação de referência da App.
a forma comum de instalar a App é incluir um fornecedor de app no seu projecto. A lista 8 mostra como você incluiria o EclipseLink como uma dependência no seu ficheiro mavenpom.xml
.
Lista 8. Incluir o EclipseLink como uma dependência Maven
org.eclipse.persistenceeclipselink2.5.0-RC1
Você também precisará incluir o driver para a sua base de dados, como mostrado na lista 9.
listagem 9. Dependência Maven para um conector MySql
mysqlmysql-connector-java5.1.32
a seguir, terá de informar o sistema sobre a sua base de dados e o seu fornecedor. Isto é feito no arquivo persistence.xml
, como mostrado na lista 10.
listagem 10. Persistência.xml
Existem outras formas de fornecer esta informação ao sistema, incluindo programaticamente. Eu recomendo usar o arquivo persistence.xml
porque armazenar dependências desta forma torna muito fácil atualizar sua aplicação sem modificar o código.
configuração da mola para a JPA
usar a mola irá facilitar muito a integração da JPA na sua aplicação. Por exemplo, a colocação do @SpringBootApplication
anotação no seu cabeçalho da aplicação instrui a Primavera para analisar automaticamente as classes e injectar o EntityManager
conforme necessário, com base na configuração que especificou.
A Lista 11 mostra as dependências a incluir se quiser o Suporte de JPA da Primavera para a sua aplicação.
Lista 11. Adicionar suporte de JPA de primavera no Maven
conclusão
cada aplicação que lida com uma base de dados deve definir uma camada de aplicação cujo único objectivo é isolar o código de persistência. Como você já viu neste artigo, a API persistência Java introduz uma gama de capacidades e suporte para persistência de objetos Java. Aplicações simples podem não exigir todas as capacidades da APP, e em alguns casos a sobrecarga de configurar o framework pode não ser merecida. À medida que uma aplicação cresce, no entanto, a estrutura e encapsulação da JPA realmente ganham a sua manutenção. O uso da JPA mantém o seu código de objeto simples e fornece um framework convencional para acessar dados em aplicações Java.
Saiba mais sobre a API de persistência Java e tecnologias relacionadas
- O que é o JDBC? Introduction to Java Database Connectivity: Get to know Java’s low-level API for connecting to a database, issuing SQL queries, and more.persistence with JPA and Hibernate, Part 1: Entities and relationships: Get started modeling entities and relationships with Java 8 and Hibernate ORM.persistência Java com JPA e Hibernato, Parte 2: Prática prática prática de modelar muitos-para-muitos relacionamentos e relacionamentos de herança em Java 8 e hibernar ORM.
- Implementing state-dependent behavior: A classic introduction to the state pattern and state dependency in Java.
- Eager / Lazy Loading In Hibernate: How to apply eager and lazy loading in Hibernate.
- JPA 2.2 traz algumas mudanças altamente esperadas: uma visão geral das atualizações de especificações na JPA 2.2, incluindo melhorias no CDI, melhor alinhamento com a API data e hora, e suporte para
@Repeatable
anotações. - deve usar a APP para o seu próximo projecto?: Questões-chave que podem ajudá-lo a decidir.