JPA/Hibernate 시작하기

JPA는 Java 지속성 API의 약자입니다.JavaEE가 Jakarta EE 프로젝트에서 Eclipse 재단에 기부했을 때 API의 명칭은 Jakarta Persistence로 바뀌었지만 JPA라는 용어는 여전히 사용되고 있다.JPA는 자바 대상을 데이터베이스 테이블에 비추어 대상 관계의 저항이 일치하지 않는 문제를 해결할 수 있도록 합니다. 자바에서 가장 많이 사용되지 않으면 지속성 프레임워크 중 하나입니다.
JPA는 실현 가능한 API 규범인 JPA 공급자 또는 실현이다.가장 유행하는 JPA 구현은 Hibernate ORM이다.JPA를 사용하지 않거나 JPA를 통해 Hibernate ORM을 사용할 수 있습니다.JPA와 결합하여 사용하는 잠재적인 장점 중 하나는 원한다면 서로 다른 실현 사이에서 이동할 수 있다는 것이다. (비록 이것은 내가 본 적이 없는 일이지만.)또 다른 장점은 경험이 있는 사람, 예를 들어 EclipseLink이나ApacheOpenJPA 등은 휴면 상태에 들어갈 때 최소한 일부 경험을 사용할 수 있다는 것이다.
이 문서는 JPA의 Hibernate 구현에서 시작합니다.우리는 표준 기능만 사용하고 기본 기능만 소개할 것이다.만약 당신이 JPA나 Hibernate에 관한 종합 과정을 배우고 싶다면, 나는 당신이 JPA spec과 정부 Hibernate docs을 읽는 것을 건의합니다.
다음은 이 개념의 실제 응용을 보지 못하도록 본 논문의 영상 버전입니다.

JPA 및 Hibernate를 Maven 프로젝트에 추가
다음은pom에 추가해야 하는 Maven 의존항입니다.xml 파일:
<dependency>
  <groupId>jakarta.persistence</groupId>
  <artifactId>jakarta.persistence-api</artifactId>
  <version>3.0.0</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core-jakarta</artifactId>
  <version>5.6.4.Final</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>3.0.0</version>
</dependency>
운전기사가 한 명 더 필요해.예를 들어, MariaDB 데이터베이스 또는 SkySQL 인스턴스를 사용하는 경우 다음을 추가합니다(최신 버전을 보려면 3.0 시리즈의 what’s new 참조).
<dependency>
  <groupId>org.mariadb.jdbc</groupId>
  <artifactId>mariadb-java-client</artifactId>
  <version>3.0.3</version>
</dependency>
Gradle을 사용하면 온라인 Maven to Gradle dependency converter을 사용할 수 있습니다.

데이터베이스 만들기
원하는 데이터베이스를 사용할 수 있지만, MariaDB를 계속합시다.

Note: You can create a MariaDB database in the cloud using SkySql. It's free and it doesn’t require credit card details. Create an account and take a look at the documentation for more information on how to get started.


SQL 클라이언트를 사용하여 데이터베이스에 연결하고 다음 데이터베이스를 만듭니다.
CREATE DATABASE jpa_demo;

지구화 단위 정의
지구화 단원은 지구화 대상을 할 수 있는 클래스의 논리 그룹과 데이터베이스 연결과 탱크 옵션 등 설정 매개 변수이다.지구화 단원은 지구화에서 정의된다.src/main/resources/META-INF/디렉토리의 xml 파일입니다.다음은 이 문서에서 사용할 방법입니다.
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
       version="2.0">
  <persistence-unit name="jpa-demo-local" transaction-type="RESOURCE_LOCAL">
    <properties>
      <property name="jakarta.persistence.jdbc.url" value="jdbc:mariadb://localhost:3306/jpa_demo"/>
      <property name="jakarta.persistence.jdbc.user" value="user"/>
      <property name="jakarta.persistence.jdbc.password" value="password"/>
      <property name="jakarta.persistence.schema-generation.database.action" value="drop-and-create"/>
    </properties>
  </persistence-unit>
</persistence>
nametransaction-type 매개 변수를 주의하십시오.모든 지구화 단원은 이름이 필요합니다. 우리는 다음 코드에서 사용할 수 있습니다.트랜잭션 유형은 트랜잭션, JPA 또는 서버를 관리하는 사용자를 나타냅니다.이 예에서 우리는 JPA가 업무를 관리하기를 원하지만 여러 개의 데이터베이스나 서비스(예를 들어 JMS와 JCA)에 걸쳐 분포식 업무를 필요로 하는 더욱 복잡한 장면에서 JTA를 사용할 것이다.이것은 우리가 본문에서 언급하지 않을 고급 주제다.
JDBC 연결 URL과 데이터베이스 사용자 및 암호를 지정하는 속성을 추가했습니다.우리는 데이터베이스 조작을 활성화해서 데이터베이스 모델을 자동으로 삭제하고 만들었다.이것은 JPA로 하여금 데이터베이스 (모든 테이블과 패턴 삭제) 를 삭제하고, 우리가 프로그램을 시작할 때 그것들을 다시 만들게 할 것이다.이것은 생산 환경에서 분명히 좋은 생각은 아니지만, 개발 과정에서 매우 유용하다. 특히 JPA 실체를 통해 데이터베이스 대상을 정의하기 시작할 때.

구현 개체
실체는 우리가 데이터베이스에서 오래 지속되기를 희망하는 실례이다.Java 주석 또는 XML을 사용하여 구성할 수 있습니다.다음 예를 검토하여 주석을 주의 깊게 살펴보십시오.
package com.example;

import jakarta.persistence.*;

import java.util.Objects;

@Entity
@Table(name = "programming_language")
public class ProgrammingLanguage {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "pl_id")
  private Integer id;

  @Column(name = "pl_name")
  private String name;

  @Column(name = "pl_rating")
  private Integer rating;

  public ProgrammingLanguage() {
  }

  public ProgrammingLanguage(String name, Integer rating) {
    this.name = name;
    this.rating = rating;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    ProgrammingLanguage that = (ProgrammingLanguage) o;
    return Objects.equals(id, that.id);
  }

  @Override
  public int hashCode() {
    return Objects.hash(id);
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getRating() {
    return rating;
  }

  public void setRating(Integer rating) {
    this.rating = rating;
  }
}
적어도 JPA 실체 클래스는 @Entity으로 표시되며, @Id으로 주석된 필드, 기본 구조 함수와 필드 액세스 (Getter) 가 있습니다.이전 예시에서, 우리는 추가 설정을 추가했다.예를 들어, 우리는 데이터베이스에 키를 할당할 수 있도록 SQL 테이블과 열 이름의 이름, 그리고 생성된 값을 설정했다.사용자 정의 구조 함수 (필요한 비arg 구조 함수를 제외하고), equals(Object), hashCode() 방법, 필드 변수 (setter) 를 추가했습니다.
JPA API의 입구점은 EntityManagerFactory 클래스입니다.Spring Framework와 JakartaEE 같은 프레임워크는 응용 프로그램에 이런 유형의 실례를 제공할 수 있다.사용하지 않는 경우 인스턴스를 생성하여 사용할 영구 단위의 이름을 지정할 수 있습니다.
EntityManagerFactory entityManagerFactory =
    Persistence.createEntityManagerFactory("jpa-demo-local");
이상적인 상황에서 모든 응용 프로그램의 지속성 단원은 EntityManagerFactory 실례만 있고 필요에 따라 EntityManager 대상을 만들어야 한다(창설 원가가 훨씬 낮다).지속성 작업은 트랜잭션 경계 내에 있어야 합니다.
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();

... persistence logic here ...

transaction.commit(); // or transaction.rollback();
EntityManager류는 데이터를 조회하고 업데이트하는 방법을 포함한다.예를 들어, 데이터베이스에 ProgrammingLanguage 객체를 저장하려면 이전 코드 세션에 다음과 같은 지속성 논리를 추가할 수 있습니다.
entityManager.persist(new ProgrammingLanguage("Java", 10));
또는 데이터베이스에 저장된 모든 프로그래밍 언어를 ProgrammingLanguage개의 객체 목록으로 사용하려는 경우
List<ProgrammingLanguage> list = entityManager.createQuery(
    "select p from ProgrammingLanguage p where p.rating > 5",
    ProgrammingLanguage.class
).getResultList();
문자열의 질의는 SQL이 아닙니다.실체(ProgrammingLanguage)를 어디서 실현했는지 기억하신다면, @Table 주석을 사용하여 표의 이름을 programming_language으로 설정합니다.검색 언어의 이름은 Jakarta Persistence Query Language(JPQL)으로 플랫폼에 독립된 대상 언어로 JPA 규범의 일부분이다.이것은 데이터베이스 조회를 데이터베이스 간에 이식할 수 있게 한다.
CheckEntityManager 인터페이스에서 사용할 수 있는 몇 가지 방법을 소개하여 모든 사용 가능한 지속적인 조작을 이해한다.이것은 JPA를 직접 사용할 때 가장 자주 사용하는 인터페이스입니다.

간단한 JPA 서비스 클래스 구현
비록 우리가 가장 간단한 용례를 사용하고 오류나 제어된 조건에서의 업무 스크롤 같은 것을 무시하지만, 간단한 조회나 저장, 삭제, 업데이트 실체를 실행하기 위해서는 5줄의 샘플 코드가 필요합니다.본고에서 실현된 자바 SE 프로그램에서 모든 샘플 코드를 봉인하고 JPA의 사용을 간소화하는 실용 프로그램 클래스를 사용하는 것은 매우 유용하다.이 유틸리티 클래스는 모든 응용 프로그램에 PersistenceManagerFactory을 만들고, 새로운 EntityManager을 만들고, 자동으로 업무를 시작하고, 닫고, 제출하는 논리를 포함해야 한다.
다음은 이러한 실용 프로그램 종류의 예로, 이것은 하나의 예로 실현되며, 고장이 발생할 때 스크롤을 담당한다.Jakarta EE 또는 Spring Data와 같은 프레임워크를 사용하는 경우에는 실제로 이러한 클래스가 필요하지 않습니다.
package com.example;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.EntityTransaction;
import jakarta.persistence.Persistence;

import java.util.function.Function;

public class JPAService {

  private static JPAService instance;
  private EntityManagerFactory entityManagerFactory;

  private JPAService() {
    entityManagerFactory = Persistence.createEntityManagerFactory("jpa-demo-local");
  }

  public static synchronized JPAService getInstance() {
    return instance == null ? instance = new JPAService() : instance;
  }

  public void shutdown() {
    if (entityManagerFactory != null) {
      entityManagerFactory.close();
      instance = null;
    }
  }

  public <T> T runInTransaction(Function<EntityManager, T> function) {
    EntityManager entityManager = entityManagerFactory.createEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    boolean success = false;
    try {
      T returnValue = function.apply(entityManager);
      success = true;
      return returnValue;

    } finally {
      if (success) {
        transaction.commit();
      } else {
        transaction.rollback();
      }
    }
  }
}
이를 통해 우리는 EntityManager에 필요한 코드를 간소화할 수 있다.예를 들어, JQL 쿼리를 실행하려면 runInTransaction(Function<EntityManager>, T) 호출에 로직을 포함해야 합니다.
List<ProgrammingLanguage> programmingLanguages = jpaService.runInTransaction(entityManager ->
    entityManager.createQuery(
        "select p from ProgrammingLanguage p where p.rating > 5",
        ProgrammingLanguage.class
    ).getResultList());
다음은 전체 Java 응용 프로그램의 예로, 응용 프로그램은 이 클래스를 사용하여 무작위 점수를 매기는 프로그래밍 언어를 만들고 5보다 큰 점수를 매기는 프로그래밍 언어를 표시합니다.
package com.example;

import java.util.Arrays;
import java.util.List;

public class Application {

  private static final JPAService jpaService = JPAService.getInstance();

  public static void main(String[] args) {
    try {
      createProgrammingLanguages();
      printTopProgrammingLanguages();

    } finally {
      jpaService.shutdown();
    }
  }

  private static void createProgrammingLanguages() {
    jpaService.runInTransaction(entityManager -> {
      Arrays.stream("Java,C++,C#,JavaScript,Rust,Go,Python,PHP".split(","))
          .map(name -> new ProgrammingLanguage(name, (int) (Math.random() * 10)))
          .forEach(entityManager::persist);
      return null;
    });
  }

  private static void printTopProgrammingLanguages() {
    List<ProgrammingLanguage> programmingLanguages = jpaService.runInTransaction(entityManager ->
        entityManager.createQuery(
            "select p from ProgrammingLanguage p where p.rating > 5",
            ProgrammingLanguage.class
        ).getResultList());

    programmingLanguages.stream()
        .map(pl -> pl.getName() + ": " + pl.getRating())
        .forEach(System.out::println);
  }
}

유용한 자원
본문에서 우리는 JPA와 Hibernate의 표면만 건드렸다.다행히도, 가장 유행하는 자바 규범 중 하나로서, 인터넷에는 대량의 유용한 자원이 있다.다음 중 일부는 다음과 같습니다.
  • The Jakarta Persistence 3.0 official page
  • The spec itself
  • The Javadoc
  • An intro to JDBC
  • The MariaDB JDBC driver documentation
  • This article as a video
  • JPA with Spring boot guide
  • JPA with Jakarta EE guide
  • 좋은 웹페이지 즐겨찾기