CodeGym /Blogue Java /Random-PT /Seu primeiro aplicativo Hibernate
John Squirrels
Nível 41
San Francisco

Seu primeiro aplicativo Hibernate

Publicado no grupo Random-PT
Neste artigo, você se familiarizará com uma das estruturas corporativas mais populares para Java e criará seu primeiro aplicativo Hibernate. Nunca ouviu falar do Hibernate? Ou talvez você já tenha ouvido falar, mas ainda não usou? Ou talvez você tentou usá-lo, mas falhou? Em todos os três casos - bem-vindo abaixo do corte :) Seu primeiro aplicativo Hibernate - 1 Olá, pessoal! Neste artigo, falarei sobre os principais recursos do framework Hibernate e ajudarei você a escrever seu primeiro mini-aplicativo. Para isso, precisamos:
  1. IntelliJ IDEA Ultimate Edition
    Faça o download no site oficial e ative a versão de teste de 30 dias.
  2. PostgreSQL - um dos sistemas de gerenciamento de banco de dados (DBMS) modernos mais populares
  3. Maven (já conectado ao IDEA)
  4. Um pouco de paciência.
Por precaução, postei o código do aplicativo no GitHub (branch codegym). O artigo destina-se principalmente àqueles que nunca trabalharam com essa tecnologia antes, então minimizei a quantidade de código. Vamos começar!

O que é Hibernar?

É uma das implementações de mapeamento objeto-relacional (ORM) mais populares. Um mapeamento objeto-relacional define o relacionamento entre objetos de software e registros de banco de dados. Obviamente, o Hibernate tem uma funcionalidade muito ampla, mas vamos nos concentrar nas funções mais simples. Nosso objetivo é criar uma aplicação CRUD (Create, Read, Update, Delete) que seja capaz de:
  1. Crie usuários (Usuário), procure-os no banco de dados por ID, atualize seus dados no banco de dados e exclua-os do banco de dados.
  2. Atribua objetos de carro (Auto) aos usuários. Crie, atualize, encontre e exclua carros do banco de dados.
  3. Além disso, o aplicativo deve remover automaticamente os carros "sem dono" do banco de dados. Em outras palavras, quando um usuário é excluído, todos os carros pertencentes a esse usuário também devem ser excluídos do banco de dados.
Nosso projeto será estruturado assim: Seu primeiro aplicativo Hibernate - 2Como você pode ver, nada complicado. 6 aulas + 1 arquivo com configs. Primeiro, crie um novo projeto Maven no IntelliJ IDEA. Arquivo -> Novo Projeto. Selecione Maven entre os tipos de projeto propostos e vá para a próxima etapa. Seu primeiro aplicativo Hibernate - 3O Apache Maven é uma estrutura para construir projetos automaticamente com base na descrição de sua estrutura em arquivos POM. Toda a estrutura do seu projeto estará descrita em pom.xml, um arquivo que o próprio IDEA criará na raiz do seu projeto. Nas configurações do projeto, você precisa especificar as seguintes configurações do Maven: groupId e artefatoId. Em projetos, groupId geralmente é uma descrição da empresa ou unidade de negócios. O nome de domínio da empresa ou site pode ir aqui. Por sua vez, artefatoId é o nome do projeto. Para groupdId, você pode inserir com.yourNickname.codegym. Isso não terá nenhum efeito no aplicativo. Para artefatoId, escolha qualquer nome de projeto que desejar. A versão pode ser deixada inalterada. Seu primeiro aplicativo Hibernate - 4Na última tela, basta confirmar os dados informados anteriormente.Seu primeiro aplicativo Hibernate - 5Então, criamos o projeto. Agora tudo o que resta a fazer é escrever algum código e fazê-lo funcionar :) Primeiras coisas primeiro: se queremos criar um aplicativo que funcione com um banco de dados, definitivamente não podemos ficar sem um banco de dados! Baixe o PostgreSQL daqui (estou usando a versão 9). O PostgreSQL tem um usuário padrão 'postgres' — você precisará criar uma senha para ele ao instalar. Não esqueça a senha. Vamos precisar dele mais tarde! (Em geral, usar o banco de dados padrão em aplicativos é uma prática ruim, mas faremos isso para reduzir o número de causas de úlceras criando seu próprio banco de dados). Se você não é amigo da linha de comando e das consultas SQL, há boas notícias. O IntelliJ IDEA fornece uma interface de usuário totalmente adequada para trabalhar com o banco de dados. Seu primeiro aplicativo Hibernate - 6(localizado no painel direito do IDEA, a guia Banco de dados). Para criar uma conexão, clique em "+" e selecione nossa fonte de dados (PostgeSQL). Preencha os campos do usuário e do banco de dados ("postgres" para ambos) e digite a senha que foi definida durante a instalação do PostgreSQL. Se necessário, baixe o driver Postgres. Você pode fazer isso na mesma página. Clique em "Test Connection" para verificar se a conexão com o banco de dados foi estabelecida. Se você vir "Bem-sucedido", siga em frente. Agora vamos criar as tabelas que precisamos. Serão dois no total: usuários e automóveis. Parâmetros para a tabela de usuários: Seu primeiro aplicativo Hibernate - 7Observe que id é a chave primária. Se você não sabe qual é a chave primária em SQL, pesquise no Google. Isso é importante. Configurações para tabela de autos: Seu primeiro aplicativo Hibernate - 8Para a tabela autos, você precisa configurar uma chave estrangeira. Ele servirá para vincular nossas tabelas. Recomendo que você leia mais a respeito. Simplificando, ele faz referência a uma tabela externa, no nosso caso, usuários. Se um carro pertencer ao usuário com id = 1, então o campo user_id dos autos será igual a 1. É assim que associamos os usuários aos seus carros em nossa aplicação. Em nossa tabela autos, o campo user_id atuará como chave estrangeira. Ele se referirá ao campo id da tabela de usuários. Seu primeiro aplicativo Hibernate - 9Então, criamos um banco de dados com duas tabelas. Resta entender como gerenciá-lo a partir do código Java. Começaremos com o arquivo pom.xml, no qual precisamos incluir as bibliotecas necessárias (no Maven são chamadas de dependências). Todas as bibliotecas são armazenadas no repositório Maven central. As bibliotecas especificadas em pom.xml estão disponíveis para uso no projeto. Seu pom.xml deve ficar assim: Seu primeiro aplicativo Hibernate - 10Nada complicado, como você pode ver. Adicionamos apenas 2 dependências — para usar PostgreSQL e Hibernate. Agora vamos passar para o código Java. Crie todos os pacotes e classes necessários no projeto. Para começar, precisamos de um modelo de dados: as classes Usere Auto.

 package models;
 
 import javax.persistence.*;
 import java.util.ArrayList;
 import java.util.List;
 
 @Entity
 @Table (name = "users")
 public class User {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private int id;
     @Column(name = "name")
     private String name;
     // You can omit the Column attribute if the name property matches the column name in the table
     private int age;
 
     @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
     private List<Auto> autos;
 
     public User() {
     }
 
     public User(String name, int age) {
         this.name = name;
         this.age = age;
         autos = new ArrayList<>();
     }
 
     public void addAuto(Auto auto) {
         auto.setUser(this);
         autos.add(auto);
     }
 
     public void removeAuto(Auto auto) {
         autos.remove(auto);
     }
 
     public int getId() {
         return id;
     }
 
     public String getName() {
         return name;
     }
 
     public void setName(String name) {
         this.name = name;
     }
 
     public int getAge() {
         return age;
     }
 
     public void setAge(int age) {
         this.age = age;
     }
 
     public List<Auto> getAutos() {
         return autos;
     }
 
     public void setAutos(List<Auto> autos) {
         this.autos = autos;
     }
 
     @Override
     public String toString() {
         return "models.User{" +
                 "id=" + id +
                 ", name='" + name + '\'' +
                 ", age=" + age +
                 '}';
     }
 }
 
 

 package models;
 
 import javax.persistence.*;
 
 @Entity
 @Table(name = "autos")
 public class Auto {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private int id;
 
     @Column (name = "model")
     private String model;
 
     // You can omit the Column attribute if the name property matches the column name in the table
     private String color;
 
 
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "user_id")
     private User user;
 
     public Auto() {
     }
 
     public Auto(String model, String color) {
         this.model = model;
         this.color = color;
     }
 
     public int getId() {
         return id;
     }
 
     public String getModel() {
         return model;
     }
 
     public void setModel(String model) {
         this.model = model;
     }
 
     public String getColor() {
         return color;
     }
 
     public void setColor(String color) {
         this.color = color;
     }
 
     public User getUser() {
         return user;
     }
 
     public void setUser(User user) {
         this.user = user;
     }
 
     @Override
     public String toString() {
         return color + " " + model;
     }
 }
 
 
Como você pode ver, as classes têm um monte de anotações obscuras. Vamos começar a investigá-los. Para nós, a anotação principal é @Entity. Leia sobre isso na Wikipedia e aprenda tudo de cor. Esta é a base da fundação. Essa anotação permite que objetos de sua classe Java sejam mapeados para um banco de dados. Para que uma classe seja uma entidade, ela deve atender aos seguintes requisitos:
  • Deve ter um construtor vazio ( publicou protected)
  • Não pode ser aninhado, uma interface ou umenum
  • Não pode ser finale não pode ter finalcampos/propriedades
  • Deve ter pelo menos um campo @Id.
Verifique suas classes de entidade: são lugares muito populares para dar um tiro no pé. É muito fácil esquecer algo. Além disso, uma entidade pode fazer o seguinte:
  • Pode ter construtores não vazios
  • Pode herdar e ser herdado
  • Pode ter outros métodos e implementar interfaces.
Como você pode ver, a Userclasse é muito semelhante à tabela de usuários. tem id, nameeageCampos. As anotações localizadas acima deles não precisam de nenhuma explicação particular: é claro que @Id indica que o campo é um identificador de objetos dessa classe. A anotação @Table acima da classe indica o nome da tabela onde os objetos são escritos. Observe o comentário acima do campo idade: se o nome do campo na classe for igual ao nome da tabela, você pode omitir a anotação @Column e funcionará. Quanto à parte indicada entre chaves ("strategy = GenerationType.IDENTITY"): existem várias estratégias para gerar IDs. Você pode pesquisá-los no Google, mas para nosso aplicativo, não precisa se preocupar. O principal é que para nossos objetos o valor de id será gerado automaticamente. Conseqüentemente, não há um setter para id e também não o configuramos no construtor. No entanto,Userclasse se destaca. Tem uma lista de carros! Seu primeiro aplicativo Hibernate - 11A anotação @OneToMany fica acima da lista. Isso significa que vários carros podem corresponder ao mesmo objeto da classe User. O elemento "mappedBy" refere-se ao campo de usuário da Autoclasse. Assim, carros e usuários estão relacionados. O elemento orphanRemoval indica se a operação de remoção deve ser aplicada a entidades que não possuem mais um relacionamento. Se excluirmos um usuário do banco de dados, todos os carros associados a ele também serão excluídos. Por sua vez, noAutoclass, você verá o campo de usuário com a anotação @ManyToOne (um usuário pode corresponder a muitos Autos) e a anotação @JoinColumn. Ele indica qual coluna na tabela autos é usada para referenciar a tabela users (ou seja, a chave estrangeira da qual falamos anteriormente). Depois de criar o modelo de dados, é hora de ensinar nosso programa a realizar operações com os dados do banco de dados. Vamos começar com a classe utilitária HibernateSessionFactoryUtil. Ele tem apenas um trabalho — criar uma fábrica de sessões para que nosso aplicativo funcione com o banco de dados (diga olá ao padrão de projeto Factory!). Não sabe fazer mais nada.

 package utils;
 
 import models.Auto;
 import models.User;
 import org.hibernate.SessionFactory;
 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 import org.hibernate.cfg.Configuration;
 
 public class HibernateSessionFactoryUtil {
     private static SessionFactory sessionFactory;
 
     private HibernateSessionFactoryUtil() {}
 
     public static SessionFactory getSessionFactory() {
         if (sessionFactory == null) {
             try {
                 Configuration configuration = new Configuration().configure();
                 configuration.addAnnotatedClass(User.class);
                 configuration.addAnnotatedClass(Auto.class);
                 StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
                 sessionFactory = configuration.buildSessionFactory(builder.build());
 
             } catch (Exception e) {
                 System.out.println("Исключение!" + e);
             }
         }
         return sessionFactory;
     }
 }
 
Nesta classe, criamos um novo objeto Configuration, e passamos a ele as classes que ele deve tratar como entidades: Usere Auto. Preste atenção ao configuration.getProperties()método. Que outras propriedades existem? De onde eles vêm? As propriedades são as configurações de hibernação indicadas no arquivo especial hibernate.cfg.xml. Seu primeiro aplicativo Hibernate - 12Hibernate.cfg.xml é lido aqui: new Configuration().configure(); Como você vê, não há nada de especial nele: ele contém os parâmetros para conexão com o banco de dados, bem como o parâmetro show_sql. Isso é necessário para que todas as consultas sql executadas pelo Hibernate sejam exibidas no console. Dessa forma, você verá exatamente o que o Hibernate está fazendo a qualquer momento, eliminando qualquer sensação de "mágica". A seguir precisamos doUserDAOaula. A melhor prática é programar por meio das interfaces — criar uma UserDAOinterface e UserDAOImpluma implementação separadas, mas vou pular isso para reduzir a quantidade de código. Não faça isso em projetos reais! O padrão de design DAO (objeto de acesso a dados) é um dos mais comuns. A ideia é simples — criar uma camada de aplicação responsável apenas pelo acesso aos dados, nada mais. Busque dados do banco de dados, atualize dados, exclua dados - é isso. Estude mais sobre DAO. Você usará objetos de acesso a dados constantemente em seu trabalho. O que nossa UserDaoclasse pode fazer? Bem, como todos os DAOs, ele só pode trabalhar com dados. Encontre um usuário por id, atualize seus dados, exclua-o, obtenha uma lista de todos os usuários do banco de dados ou salve um novo usuário no banco de dados - essa é a totalidade de sua funcionalidade.

 package dao;
 
 import models.Auto;
 import models.User;
 import org.hibernate.Session;
 import org.hibernate.Transaction;
 import utils.HibernateSessionFactoryUtil;
 import java.util.List;
 
 public class UserDao {
 
     public User findById(int id) {
         return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(User.class, id);
     }
 
     public void save(User user) {
         Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
         Transaction tx1 = session.beginTransaction();
         session.save(user);
         tx1.commit();
         session.close();
     }
 
     public void update(User user) {
         Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
         Transaction tx1 = session.beginTransaction();
         session.update(user);
         tx1.commit();
         session.close();
     }
 
     public void delete(User user) {
         Session session = HibernateSessionFactoryUtil.getSessionFactory().openSession();
         Transaction tx1 = session.beginTransaction();
         session.delete(user);
         tx1.commit();
         session.close();
     }
 
     public Auto findAutoById(int id) {
         return HibernateSessionFactoryUtil.getSessionFactory().openSession().get(Auto.class, id);
     }
 
     public List<User> findAll() {
         List<User> users = (List<User>) HibernateSessionFactoryUtil.getSessionFactory().openSession().createQuery("From User").list();
         return users;
     }
 }
 
UserDaoOs métodos de são semelhantes entre si. Na maioria deles, obtemos um objeto Session (sessão de conexão com o banco de dados) usando nossa Session Factory, criamos uma única transação dentro dessa sessão, realizamos as manipulações de dados necessárias, salvamos o resultado da transação no banco de dados e fechamos a sessão. Os próprios métodos, como você pode ver, são bastante simples. DAO é o "coração" da nossa aplicação. No entanto, não criaremos um DAO diretamente e chamaremos seus métodos em nosso main()método. Toda a lógica será movida para a UserServiceclasse.

 package services;
 
 import dao.UserDao;
 import models.Auto;
 import models.User;
 
 import java.util.List;
 
 public class UserService {
 
     private UserDao usersDao = new UserDao();
 
     public UserService() {
     }
 
     public User findUser(int id) {
         return usersDao.findById(id);
     }
 
     public void saveUser(User user) {
         usersDao.save(user);
     }
 
     public void deleteUser(User user) {
         usersDao.delete(user);
     }
 
     public void updateUser(User user) {
         usersDao.update(user);
     }
 
     public List<User> findAllUsers() {
         return usersDao.findAll();
     }
 
     public Auto findAutoById(int id) {
         return usersDao.findAutoById(id);
     }
 
 
 }
 
 
Um serviço é uma camada de dados do aplicativo responsável por executar a lógica de negócios. Se o seu programa precisar executar algum tipo de lógica de negócios, ele o fará por meio de serviços. Um serviço contém UserDaoe chama métodos DAO em seus métodos. Pode parecer que estamos duplicando funções aqui (por que não apenas chamar os métodos de um objeto DAO?), mas com muitos objetos e lógica complexa, a camada do aplicativo oferece grandes vantagens (fazer isso é uma boa prática — lembre-se disso no futuro e leia sobre "camadas de aplicação"). Nosso serviço tem uma lógica simples, mas os métodos de serviço em projetos do mundo real contêm muito mais do que uma linha de código :) Agora temos tudo o que você precisa para executar o aplicativo! No main()método, vamos criar um usuário e seu carro, associar um ao outro e salvá-los no banco de dados.

 import models.Auto;
 import models.User;
 import services.UserService;
 
 import java.sql.SQLException;
 
 public class Main {
     public static void main(String[] args) throws SQLException {
 
         UserService userService = new UserService();
         User user = new User ("Jenny", 26);
         userService.saveUser(user);
         Auto ferrari = new Auto("Ferrari", "red");
         ferrari.setUser(user);
         user.addAuto(ferrari);
         Auto ford = new Auto("Ford", "black");
         ford.setUser(user);
         user.addAuto(ford);
         userService.updateUser(user);
     }
 }
 
 
Como você pode ver, a tabela de usuários tem seu próprio registro e a tabela de autos tem seu próprio registro. Seu primeiro aplicativo Hibernate - 13Seu primeiro aplicativo Hibernate - 14Vamos tentar renomear nosso usuário. Limpe a tabela de usuários e execute o código

 import models.Auto;
 import models.User;
 import services.UserService;
 
 import java.sql.SQLException;
 
 public class Main {
     public static void main(String[] args) throws SQLException {
 
         UserService userService = new UserService();
         User user = new User ("Jenny", 26);
         userService.saveUser(user);
         Auto ferrari = new Auto("Ferrari", "red");
         user.addAuto(ferrari);
         Auto ford = new Auto("Ford", "black");
         ford.setUser(user);
         user.addAuto(ford);
         userService.updateUser(user);
         user.setName ("Benny");
         userService.updateUser(user);
     }
 }
 
 
Funciona! Seu primeiro aplicativo Hibernate - 15E se você deletar o usuário? Limpe a tabela de usuários (os autos serão limpos) e execute o código

 import models.Auto;
 import models.User;
 import services.UserService;
 
 import java.sql.SQLException;
 
 public class Main {
     public static void main(String[] args) throws SQLException {
 
         UserService userService = new UserService();
         User user = new User ("Jenny", 26);
         userService.saveUser(user);
         Auto ferrari = new Auto("Ferrari", "red");
         user.addAuto(ferrari);
         Auto ford = new Auto("Ford", "black");
         ford.setUser(user);
         user.addAuto(ford);
         userService.updateUser(user);
         user.setName ("Benny");
         userService.updateUser(user);
         userService.deleteUser(user);
     }
 }
 
 
E nossas tabelas estão completamente vazias (preste atenção no console — todas as requisições feitas pelo Hibernate serão exibidas lá). Você pode brincar com o aplicativo e experimentar todas as suas funções. Por exemplo, crie um usuário com carros, salve-o no banco de dados, veja o id atribuído ao usuário e tente usar esse id nomain()para buscar o usuário no banco de dados e exibir uma lista de seus carros no console. Obviamente, vimos apenas uma pequena parte da funcionalidade do Hibernate. Seus recursos são muito amplos e há muito tempo é uma ferramenta padrão da indústria para desenvolvimento Java. Se você quiser estudá-lo em detalhes, posso recomendar o livro "Java Persistence API and Hibernate". Eu revisei em um artigo anterior. Espero que este artigo tenha sido útil para os leitores. Se você tiver dúvidas, pergunte nos comentários. Ficarei feliz em responder :) Além disso, não se esqueça de apoiar o autor no concurso postando um "Curtir". Ou melhor ainda — "Adorei" :) Boa sorte nos seus estudos!
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION