CodeGym /Java Blog /무작위의 /첫 번째 Hibernate 애플리케이션
John Squirrels
레벨 41
San Francisco

첫 번째 Hibernate 애플리케이션

무작위의 그룹에 게시되었습니다
이 기사에서 가장 인기 있는 Java용 엔터프라이즈 프레임워크 중 하나에 익숙해지고 첫 번째 Hibernate 애플리케이션을 만들 것입니다. 최대 절전 모드에 대해 들어 본 적이 없습니까? 아니면 들어는 봤지만 사용해본 적은 없으신가요? 아니면 사용하려고 했지만 실패했습니까? 세 가지 경우 모두 - 컷 아래에 오신 것을 환영합니다 :) 첫 번째 Hibernate 애플리케이션 - 1 안녕하세요 여러분! 이 기사에서는 Hibernate 프레임워크의 주요 기능에 대해 이야기하고 첫 번째 미니 애플리케이션을 작성하는 데 도움을 줄 것입니다. 이를 위해서는 다음이 필요합니다.
  1. IntelliJ IDEA Ultimate Edition 공식 웹사이트
    에서 다운로드하고 30일 체험판을 활성화하세요.
  2. PostgreSQL - 가장 널리 사용되는 최신 데이터베이스 관리 시스템(DBMS) 중 하나
  3. Maven(이미 IDEA에 연결됨)
  4. 약간의 인내심.
만일을 대비하여 애플리케이션 코드를 GitHub (codegym 브랜치)에 게시했습니다. 이 기사는 주로 이전에 이 기술로 작업한 적이 없는 사람들을 대상으로 하므로 코드의 양을 최소화했습니다. 시작하자!

최대 절전 모드 란 무엇입니까?

가장 널리 사용되는 ORM(개체 관계형 매핑) 구현 중 하나입니다. 개체 관계형 매핑은 소프트웨어 개체와 데이터베이스 레코드 간의 관계를 정의합니다. 물론 Hibernate는 매우 광범위한 기능을 가지고 있지만 우리는 가장 간단한 기능에 초점을 맞출 것입니다. 우리의 목표는 다음을 수행할 수 있는 CRUD(만들기, 읽기, 업데이트, 삭제) 애플리케이션을 만드는 것입니다.
  1. 사용자(User)를 생성하고, ID로 데이터베이스에서 검색하고, 데이터베이스에서 데이터를 업데이트하고, 데이터베이스에서 삭제합니다.
  2. 사용자에게 자동차 개체(자동)를 할당합니다. 데이터베이스에서 자동차를 생성, 업데이트, 찾기 및 삭제합니다.
  3. 또한 애플리케이션은 데이터베이스에서 "소유자 없는" 자동차를 자동으로 제거해야 합니다. 즉, 사용자가 삭제되면 해당 사용자에게 속한 모든 자동차도 데이터베이스에서 삭제되어야 합니다.
우리 프로젝트는 다음과 같이 구성될 것입니다. 첫 번째 Hibernate 애플리케이션 - 2보시다시피 복잡한 것은 없습니다. 6개의 클래스 + 구성이 있는 1개의 파일. 먼저 IntelliJ IDEA에서 새 Maven 프로젝트를 만듭니다. 파일 -> 새 프로젝트. 제안된 프로젝트 유형 중 Maven을 선택하고 다음 단계로 이동합니다. 첫 번째 Hibernate 애플리케이션 - 3Apache Maven은 POM 파일의 구조 설명을 기반으로 프로젝트를 자동으로 빌드하기 위한 프레임워크입니다. 프로젝트의 전체 구조는 IDEA가 프로젝트의 루트에 생성하는 파일인 pom.xml에 설명되어 있습니다. 프로젝트 설정에서 다음 Maven 설정(groupId 및 artifactId)을 지정해야 합니다. 프로젝트에서 groupId는 일반적으로 회사 또는 비즈니스 단위에 대한 설명입니다. 회사 또는 웹사이트의 도메인 이름을 여기에 입력할 수 있습니다. 차례로, artifactId는 프로젝트의 이름입니다. groupdId에 를 입력할 수 있습니다 com.yourNickname.codegym. 응용 프로그램에는 아무런 영향을 미치지 않습니다. artifactId의 경우 원하는 프로젝트 이름을 선택합니다. 버전은 변경하지 않고 그대로 둘 수 있습니다. 첫 번째 Hibernate 애플리케이션 - 4마지막 화면에서 이전에 입력한 데이터를 확인하기만 하면 됩니다.첫 번째 Hibernate 애플리케이션 - 5그래서 우리는 프로젝트를 만들었습니다. 이제 남은 일은 코드를 작성하고 작동시키는 것입니다 :) 가장 먼저 해야 할 일: 데이터베이스와 함께 작동하는 애플리케이션을 만들고 싶다면 데이터베이스 없이는 절대 할 수 없습니다! 여기 에서 PostgreSQL을 다운로드합니다 (저는 버전 9를 사용하고 있습니다). PostgreSQL에는 기본 사용자 'postgres'가 있습니다 — 설치할 때 암호를 생각해야 합니다. 비밀번호를 잊지 마세요. 나중에 필요합니다! (일반적으로 응용 프로그램에서 기본 데이터베이스를 사용하는 것은 좋지 않지만 자체 데이터베이스를 만들어 궤양 원인의 수를 줄이기 위해 그렇게 할 것입니다.) 명령줄 및 SQL 쿼리와 친구가 아닌 경우 좋은 소식이 있습니다. IntelliJ IDEA는 데이터베이스 작업에 완전히 적합한 사용자 인터페이스를 제공합니다. 첫 번째 Hibernate 애플리케이션 - 6(IDEA의 오른쪽 창인 데이터베이스 탭에 있음). 연결을 생성하려면 "+"를 클릭하고 데이터 소스(PostgeSQL)를 선택합니다. 사용자 및 데이터베이스(둘 다 "postgres") 필드를 채우고 PostgreSQL 설치 중에 설정한 암호를 입력합니다. 필요한 경우 Postgres 드라이버를 다운로드합니다. 동일한 페이지에서 이 작업을 수행할 수 있습니다. "연결 테스트"를 클릭하여 데이터베이스 연결이 설정되었는지 확인하십시오. "성공"이 표시되면 계속 진행합니다. 이제 필요한 테이블을 생성합니다. 사용자와 자동의 총 2가지가 있습니다. 사용자 테이블의 매개변수: 첫 번째 Hibernate 애플리케이션 - 7id는 기본 키입니다. SQL에서 기본 키가 무엇인지 모르면 Google에서 검색하십시오. 이건 중요하다. autos 테이블 설정: 첫 번째 Hibernate 애플리케이션 - 8autos 테이블의 경우 외래 키를 구성해야 합니다. 테이블을 연결하는 역할을 합니다. 자세한 내용을 읽어 보시기 바랍니다. 간단히 말해서 외부 테이블(여기서는 사용자)을 참조합니다. 자동차가 id = 1인 사용자에게 속한 경우 autos의 user_id 필드는 1과 같습니다. 이것이 우리가 애플리케이션에서 사용자를 자동차와 연결하는 방법입니다. autos 테이블에서 user_id 필드는 외래 키 역할을 합니다. 사용자 테이블의 id 필드를 참조합니다. 첫 번째 Hibernate 애플리케이션 - 9그래서 두 개의 테이블이 있는 데이터베이스를 만들었습니다. 남은 것은 Java 코드에서 관리하는 방법을 이해하는 것입니다. 필요한 라이브러리를 포함해야 하는 pom.xml 파일부터 시작하겠습니다(Maven에서는 종속성이라고 함). 모든 라이브러리는 중앙 Maven 저장소에 저장됩니다. pom.xml에서 지정하는 라이브러리는 프로젝트에서 사용할 수 있습니다. pom.xml은 다음과 같아야 합니다. 첫 번째 Hibernate 애플리케이션 - 10보시다시피 복잡하지 않습니다. PostgreSQL 및 Hibernate를 사용하기 위해 2개의 종속성만 추가했습니다. 이제 Java 코드로 이동하겠습니다. 프로젝트에서 필요한 모든 패키지와 클래스를 만듭니다. 시작하려면 데이터 모델( UserAuto클래스)이 필요합니다.

 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;
     }
 }
 
 
보시다시피 클래스에는 모호한 주석이 많이 있습니다. 그것들을 파헤쳐 봅시다. 우리에게 주요 주석은 @Entity입니다. Wikipedia에서 그것에 대해 읽고 마음으로 배우십시오. 이것이 재단의 기초입니다. 이 주석을 사용하면 Java 클래스의 개체를 데이터베이스에 매핑할 수 있습니다. 클래스가 엔터티가 되려면 다음 요구 사항을 충족해야 합니다.
  • public빈 생성자( 또는 protected) 가 있어야 합니다.
  • 중첩, 인터페이스 또는enum
  • 필드/속성 일 수 없으며 final가질 수도 없습니다.final
  • 하나 이상의 @Id 필드가 있어야 합니다.
엔터티 클래스를 확인하십시오. 자신의 발을 쏠 수 있는 매우 인기 있는 장소입니다. 무언가를 잊는 것은 매우 쉽습니다. 또한 엔티티는 다음을 수행할 수 있습니다.
  • 비어 있지 않은 생성자를 가질 수 있습니다.
  • 물려받을 수도 있고 상속받을 수도 있다
  • 다른 메소드를 가질 수 있고 인터페이스를 구현할 수 있습니다.
보시다시피 User클래스는 users 테이블과 매우 유사합니다. id, name, 및age필드. 그 위에 있는 주석은 특별한 설명이 필요하지 않습니다. @Id는 필드가 이 클래스의 개체 식별자임을 나타냅니다. 클래스 위의 @Table 주석은 개체가 기록되는 테이블의 이름을 나타냅니다. 나이 필드 위의 주석에 유의하십시오. 클래스의 필드 이름이 테이블 이름과 동일한 경우 @Column 주석을 생략할 수 있으며 작동합니다. 중괄호 안에 표시된 부분("strategy = GenerationType.IDENTITY"): ID를 생성하기 위한 몇 가지 전략이 있습니다. Google에서 검색할 수 있지만 우리 애플리케이션의 경우 귀찮게 할 필요가 없습니다. 가장 중요한 것은 객체의 경우 id 값이 자동으로 생성된다는 것입니다. 따라서 id에 대한 setter가 없으며 생성자에서도 설정하지 않습니다. 하지만,User수업이 눈에 띕니다. 자동차 목록이 있습니다! 첫 번째 Hibernate 애플리케이션 - 11@OneToMany 주석은 목록 위에 있습니다. 이는 여러 대의 자동차가 User 클래스의 동일한 개체에 해당할 수 있음을 의미합니다. "mappedBy" 요소는 클래스의 사용자 필드를 참조합니다 Auto. 따라서 자동차와 사용자는 관련이 있습니다. orphanRemoval 요소는 더 이상 관계가 없는 엔터티에 제거 작업을 적용할지 여부를 나타냅니다. 데이터베이스에서 사용자를 삭제하면 관련된 모든 자동차도 삭제됩니다. 차례로,Auto클래스에서 @ManyToOne 주석(하나의 사용자가 여러 Auto에 해당할 수 있음) 및 @JoinColumn 주석이 있는 사용자 필드를 볼 수 있습니다. 이것은 autos 테이블에서 users 테이블을 참조하기 위해 사용되는 열을 나타냅니다(예: 이전에 이야기한 외래 키). 데이터 모델을 만든 후에는 데이터베이스의 데이터로 작업을 수행하도록 프로그램을 가르칠 때입니다. HibernateSessionFactoryUtil 유틸리티 클래스부터 시작하자. 애플리케이션이 데이터베이스와 함께 작동하도록 세션 팩토리를 생성하는 작업이 하나뿐입니다(팩토리 디자인 패턴을 소개합니다!). 다른 작업을 수행하는 방법을 모릅니다.

 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;
     }
 }
 
이 클래스에서 새 구성 개체를 만들고 엔터티로 취급해야 하는 클래스 User및 에 전달합니다 Auto. 방법 에 주의하세요 configuration.getProperties(). 어떤 다른 속성이 있습니까? 그들은 어디에서 왔니? 속성은 특별한 hibernate.cfg.xml 파일에 표시된 최대 절전 모드 설정입니다. 첫 번째 Hibernate 애플리케이션 - 12Hibernate.cfg.xml은 여기에서 읽을 수 있습니다. new Configuration().configure(); 보시다시피 특별히 특별한 것은 없습니다. 데이터베이스에 연결하기 위한 매개변수와 show_sql 매개변수가 포함되어 있습니다. 이는 Hibernate에 의해 실행되는 모든 SQL 쿼리가 콘솔에 표시되도록 하기 위해 필요합니다. 이 방법을 사용하면 주어진 순간에 Hibernate가 수행하는 작업을 정확히 볼 수 있으므로 "마법"이라는 느낌을 제거할 수 있습니다. 다음으로 우리는UserDAO수업. 가장 좋은 방법은 인터페이스를 통해 프로그래밍하는 것입니다. 즉, 별도의 UserDAO인터페이스와 UserDAOImpl구현을 생성하지만 코드 양을 줄이기 위해 생략하겠습니다. 실제 프로젝트에서는 이렇게 하지 마세요! DAO(데이터 액세스 개체) 디자인 패턴은 가장 일반적인 패턴 중 하나입니다. 아이디어는 간단합니다. 데이터 액세스만 담당하는 애플리케이션 계층을 생성하는 것입니다. 데이터베이스에서 데이터를 가져오고, 데이터를 업데이트하고, 데이터를 삭제합니다. 그게 다입니다. DAO에 대해 자세히 알아보십시오. 작업에서 지속적으로 데이터 액세스 개체를 사용하게 됩니다. 우리 UserDao반은 무엇을 할 수 있습니까? 음, 모든 DAO와 마찬가지로 데이터로만 작동할 수 있습니다. ID로 사용자를 찾고, 데이터를 업데이트하고, 삭제하고, 데이터베이스에서 모든 사용자 목록을 가져오고, 데이터베이스에 새 사용자를 저장하는 것이 전체 기능입니다.

 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;
     }
 }
 
UserDao의 방법은 서로 비슷합니다. 대부분의 경우 Session Factory를 사용하여 Session 개체(데이터베이스 연결 세션)를 가져오고 이 세션 내에서 단일 트랜잭션을 생성하고 필요한 데이터 조작을 수행하고 트랜잭션 결과를 데이터베이스에 저장한 다음 세션을 닫습니다 . 보시다시피 방법 자체는 매우 간단합니다. DAO는 우리 애플리케이션의 "심장"입니다. 그러나 DAO를 직접 생성하지 않고 main()메서드에서 해당 메서드를 호출합니다. 모든 논리가 클래스로 이동됩니다 UserService.

 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);
     }
 
 
 }
 
 
서비스는 비즈니스 로직 실행을 담당하는 애플리케이션 데이터 계층입니다. 프로그램이 일종의 비즈니스 로직을 실행해야 하는 경우 서비스를 통해 수행합니다. 서비스는 를 포함 UserDao하고 해당 메서드에서 DAO 메서드를 호출합니다. 여기에서 함수를 복제하는 것처럼 보일 수 있지만(DAO 개체에서 메서드를 호출하는 것만으로는 안 되는 이유는 무엇입니까?) 많은 개체와 복잡한 논리가 있는 경우 응용 프로그램을 계층화하면 큰 이점이 있습니다(그렇게 하는 것이 좋은 방법입니다. 나중에 이를 기억하십시오. "응용 프로그램 계층"에 대해 읽어보십시오). 우리 서비스는 간단한 논리를 가지고 있지만 실제 프로젝트의 서비스 메서드에는 한 줄 이상의 코드가 포함되어 있습니다 :) 이제 애플리케이션을 실행하는 데 필요한 모든 것이 있습니다! 메서드 에서 main()사용자와 자동차를 만들고 서로 연결하고 데이터베이스에 저장해 보겠습니다.

 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);
     }
 }
 
 
보시다시피 users 테이블에는 자체 레코드가 있고 autos 테이블에는 자체 레코드가 있습니다. 첫 번째 Hibernate 애플리케이션 - 13첫 번째 Hibernate 애플리케이션 - 14사용자 이름을 변경해 보겠습니다. 사용자 테이블을 지우고 코드를 실행하십시오.

 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);
     }
 }
 
 
효과가있다! 첫 번째 Hibernate 애플리케이션 - 15사용자를 삭제하면 어떻게 되나요? 사용자 테이블을 지우고(autos는 자체적으로 지워짐) 코드를 실행합니다.

 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);
     }
 }
 
 
그리고 테이블은 완전히 비어 있습니다(콘솔에 주의하십시오. Hibernate에 의해 수행된 모든 요청이 콘솔에 표시될 것입니다). 응용 프로그램을 가지고 놀면서 모든 기능을 사용해 볼 수 있습니다. 예를 들어 자동차 사용자를 생성하여 데이터베이스에 저장하고 사용자에게 할당된 ID를 확인하고 이 ID를 다음에서 사용하려고 합니다.main()데이터베이스에서 사용자를 가져오고 콘솔에 자동차 목록을 표시하는 메서드입니다. 물론 우리는 Hibernate 기능의 일부만을 보았다. 그 기능은 매우 광범위하며 오랫동안 Java 개발을 위한 표준 산업 도구였습니다. 자세히 공부하고 싶다면 "Java Persistence API와 Hibernate"라는 책을 추천할 수 있습니다. 이전 기사에서 검토했습니다. 이 글이 독자들에게 도움이 되었기를 바랍니다. 질문이 있으면 의견에 질문하십시오. 기꺼이 답변해 드리겠습니다 :) 또한 "좋아요"를 게시하여 콘테스트에서 작성자를 지원하는 것을 잊지 마십시오. 또는 더 좋은 방법은 — "Love it" :) 학업에 행운을 빕니다!
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION