Hibernate: como cozinhar

Boa noite, Habr.

Este artigo é uma tentativa de facilitar a busca de pessoas que iniciam no hibernate e enfrentam a mesma pergunta que eu - a saber, como escrever corretamente nesta ferramenta . (Isso será especialmente útil para programadores que acessam java a partir de linguagens de tipo fraco). Não haverá código, haverá princípios básicos sobre como usar essa tecnologia produtivamente. Tudo escrito sob o corte é o meu IMHO, não reivindicando a única solução possível para o problema.

Então



Faça imediatamente uma reserva de que minha experiência foi com o Spring Data JPA .

Como o Hibernate é uma estrutura corporativa, é difícil encontrar exemplos de código mais profundos que o CRUD comum. Esse fato complica seriamente o entendimento de como escrever no Hiber, como os próprios desenvolvedores do framework imaginaram um bom código - como resultado, tive que pensar sobre esse problema. Tenho certeza de que não estou sozinha.

@


A primeira coisa a notar é que não há banco de dados como uma abstração. No hibernate, tudo foi feito para obter controle total sobre o banco de dados no código (você pode pesquisar no Google Entity Management). Seu banco de dados são objetos de domínio que desempenham a função de armazenamento quase estúpido. Daí uma regra importante: não os use para nada além de armazenamento. Eles não devem executar as funções de um DTO que aceita entrada do usuário e não devem servir como exibição durante a serialização. Eles têm patas.

Incrível, mas verdadeiro
Em geral, é surpreendente que eu não tenha visto no segmento educacional da Internet (incluindo o inglês) um exemplo de uso de classes adicionais para serialização, por exemplo, em json. Quem nunca disse que, se você tem um serviço REST, não precisa se preocupar com as classes de exibição?)

Sim, e não para o REST, a intuição sugere que apenas o conjunto de dados de que ele precisa será enviado ao cliente em bom tom, enquanto todos os dados estiverem prontos (e você não precisou chamar getters no cliente para uma inicialização lenta).

@


Isso implica a seguinte regra - eles não devem se importar com o formato de uso. Se precisarmos de uma lista de produtos (onde apenas o nome e a descrição estarão) ou uma página do produto (com fotos e críticas) - o cliente receberá em um caso uma List do SimpleProductViewer (id, name, description) e no outro ExtendedProductViewer (id, name, description, List(photos), List(reviews), rating) , que serão geradas nos métodos da classe ProductService e usarão as classes de domínio apenas como fonte de dados.

A mesma coisa com a entrada. Aqui é Java, aqui está tudo bem em fazer DTO com campos diferentes para cada caso :)

Como exemplo, aumentarei a base de classes para o domínio Produto hackeado. O que já temos:

  1. Produto (domínio)
  2. Visualizador (classes para exibição de informações pelo cliente, pode ser qualquer número)
  3. Dto (as classes para obter informações também podem ser qualquer número)
  4. Repositório (para recebimento de dados)
  5. Serviço (ou gerente) - uma caixa preta para lógica de negócios não controlada, que combina todos os pontos anteriores.

@


Parece-me (ao que parece) que o Java Enterprise não está muito otimizado (isso já pode ser visto a pedido do hibernate e o próprio fato de o OOP (hibernate) ter assumido a responsabilidade pelo gerenciamento de entidades de banco de dados). Portanto, acredito que o principal nesse contexto é a correspondência do código com as idéias dos desenvolvedores do framework, e não a estratégia ideal.

@


Se você observar os domínios de hibernação dessa maneira (apenas armazenamento de dados), o @ManyToOne parece ser um mecanismo que não é usado com tanta frequência e se aplica apenas a tabelas completamente dependentes - imagens, revisões, comentários. Em princípio, isso é normal - na minha opinião, não é necessário estender seu efeito às tabelas principais do seu banco de dados.

Resumindo


  • Use o domínio apenas para armazenamento de dados, é desejável que as propriedades da classe estejam contidas na tabela de banco de dados de destino, ou seja, não exista nada de supérfluo (ditado pela lógica de negócios).
  • Não é necessário tentar expandir o domínio - estenda as classes de exibição e use as classes de domínio apenas como um provedor de dados.
  • Não tenha medo de produzir o mesmo tipo de classe - a compreensão e a flexibilidade do uso são mais importantes. O máximo que pode ser feito para reduzir a quantidade de código é herdá-los do domínio.
  • Não persiga a otimização. Para os meninos Java, isso não é importante, embora, é claro, tudo dependa do contexto.

Algo assim.

Source: https://habr.com/ru/post/pt484772/


All Articles