JavaRush /Java Blog /Random-KO /JPA: 기술 소개
Viacheslav
레벨 3

JPA: 기술 소개

Random-KO 그룹에 게시되었습니다
현대 개발 세계는 삶을 더 편리하게 만들기 위해 고안된 다양한 사양으로 가득 차 있습니다. 도구를 알면 올바른 도구를 선택할 수 있습니다. 모르면 인생이 더 힘들어질 수 있습니다. 이 검토에서는 JPA(Java Persistence API) 개념에 대한 비밀의 베일이 벗겨질 것입니다. 이 책을 읽은 후에는 이 신비한 세계에 더욱 깊이 빠져들고 싶어지기를 바랍니다.
JPA : 기술개론 - 1

소개

우리가 알고 있듯이 프로그램의 주요 작업 중 하나는 데이터를 저장하고 처리하는 것입니다. 예전에는 사람들이 단순히 데이터를 파일에 저장했습니다. 그러나 동시 읽기 및 편집 액세스가 필요한 순간, 로드가 있는 경우(즉, 여러 요청이 동시에 도착하는 경우) 단순히 데이터를 파일에 저장하는 것은 문제가 됩니다. 데이터베이스가 해결하는 문제와 방법에 대한 자세한 내용을 보려면 " 데이터베이스의 구조 " 기사를 읽어 보시기 바랍니다 . 이는 우리가 데이터를 데이터베이스에 저장하기로 결정했음을 의미합니다. 오랫동안 Java는 JDBC API(Java Database Connectivity)를 사용하여 데이터베이스와 작업할 수 있었습니다. JDBC에 대한 자세한 내용은 여기에서 확인할 수 있습니다. " JDBC 또는 모든 것이 시작되는 곳 " 그러나 시간이 흐르고 개발자들은 데이터베이스에 Java 객체를 저장하거나 그 반대로, 데이터베이스의 데이터를 사용하여 Java 객체를 생성하는 사소한 작업을 위해 동일한 유형과 불필요한 "유지 관리" 코드(소위 보일러플레이트 코드)를 작성해야 하는 필요성에 매번 직면했습니다. 데이터 베이스. 그리고 이러한 문제를 해결하기 위해 ORM이라는 개념이 탄생했습니다. ORM - 객체 관계형 매핑(Object-Relational Mapping) 또는 러시아어 객체 관계형 매핑으로 번역됩니다. 객체지향 프로그래밍 언어의 개념과 데이터베이스를 연결하는 프로그래밍 기술이다. 단순화하기 위해 ORM은 Java 개체와 데이터베이스의 레코드 간의 연결입니다. JPA: 기술 소개 - 2ORM은 기본적으로 Java 개체가 데이터베이스의 데이터로 표시될 수 있다는 개념입니다(그 반대도 마찬가지임). 이는 JPA 사양인 Java Persistence API의 형태로 구현되었습니다. 스펙은 이미 이 개념을 표현한 Java API에 대한 설명입니다. 사양은 ORM 개념에 따라 작업하기 위해 어떤 도구를 제공해야 하는지(즉, 어떤 인터페이스를 통해 작업할 수 있는지) 알려줍니다. 그리고 이 자금을 어떻게 사용하는지. 사양에서는 도구 구현을 설명하지 않습니다. 이를 통해 하나의 사양에 대해 서로 다른 구현을 사용할 수 있습니다. 단순화하여 사양은 API에 대한 설명이라고 말할 수 있습니다. JPA 사양의 텍스트는 Oracle 웹사이트 " JSR 338: JavaTM Persistence API "에서 찾을 수 있습니다. 따라서 JPA를 사용하려면 해당 기술을 사용할 구현이 필요합니다. JPA 구현은 JPA 제공자라고도 합니다. 가장 주목할만한 JPA 구현 중 하나는 Hibernate 입니다 . 그러므로 나는 그것을 고려할 것을 제안합니다.
JPA: 기술 소개 - 3

프로젝트 만들기

JPA는 Java에 관한 것이므로 Java 프로젝트가 필요합니다. 우리는 직접 디렉토리 구조를 수동으로 생성하고 필요한 라이브러리를 직접 추가할 수 있었습니다. 그러나 프로젝트 조립을 자동화하기 위한 시스템을 사용하는 것이 훨씬 더 편리하고 정확합니다(즉, 본질적으로 이것은 우리를 위해 프로젝트 조립을 관리하는 프로그램일 뿐입니다. 디렉토리 생성, 클래스 경로에 필요한 라이브러리 추가 등) .). 그러한 시스템 중 하나가 Gradle입니다. Gradle에 대한 자세한 내용은 " A Brief Introduction to Gradle " 에서 확인할 수 있습니다 . 우리가 알고 있듯이 Gradle 기능(즉, 수행할 수 있는 작업)은 다양한 Gradle 플러그인을 사용하여 구현됩니다. Gradle과 " Gradle Build Init Plugin " 플러그인을 사용해 보겠습니다 . 다음 명령을 실행해 보겠습니다.

gradle init --type java-application
Gradle은 우리를 위해 필요한 디렉토리 구조를 수행하고 빌드 스크립트에서 프로젝트에 대한 기본 선언적 설명을 생성합니다 build.gradle. 그래서 우리에게는 신청서가 있습니다. 우리는 애플리케이션을 통해 무엇을 설명하거나 모델링하고 싶은지 생각해야 합니다. 예를 들어 app.quickdatabasediagrams.com 과 같은 몇 가지 모델링 도구를 사용해 보겠습니다. JPA: 기술 소개 - 4여기에서 우리가 설명한 것이 "도메인 모델"이라고 말할 가치가 있습니다. 도메인은 "주제 영역"입니다. 일반적으로 도메인은 라틴어로 '소유'입니다. 중세 시대에는 왕이나 봉건 영주가 소유한 지역에 붙여진 이름이었습니다. 그리고 프랑스어에서는 단순히 "지역"으로 번역되는 "domaine"이라는 단어가 되었습니다. 따라서 우리는 "도메인 모델" = "주제 모델"을 설명했습니다. 이 모델의 각 요소는 실제 생활에서 나온 일종의 "본질"입니다. 우리의 경우 항목은 카테고리( Category), 주제( Topic)입니다. 예를 들어 이름 모델을 사용하여 엔터티에 대한 별도의 패키지를 만들어 보겠습니다. 그리고 거기에 엔터티를 설명하는 Java 클래스를 추가해 보겠습니다. Java 코드에서 이러한 엔터티는 다음과 같은 일반 POJO 입니다.
public class Category {
    private Long id;
    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}
클래스의 내용을 복사하여 비유적으로 클래스를 생성해 보겠습니다 Topic. 그는 자신이 속한 범주에 대해 알고 있는 것만 다를 것입니다. Topic따라서 카테고리 필드와 이를 사용하기 위한 메서드를 클래스에 추가해 보겠습니다 .
private Category category;

public Category getCategory() {
	return category;
}

public void setCategory(Category category) {
	this.category = category;
}
이제 자체 도메인 모델을 가진 Java 애플리케이션이 생겼습니다. 이제 JPA 프로젝트에 연결을 시작할 차례입니다.
JPA: 기술 소개 - 5

JPA 추가

기억하는 것처럼 JPA는 데이터베이스에 무언가를 저장한다는 의미입니다. 그러므로 데이터베이스가 필요합니다. 프로젝트에서 데이터베이스 연결을 사용하려면 데이터베이스에 연결하기 위한 종속성 라이브러리를 추가해야 합니다. 우리가 기억하는 것처럼 우리는 우리를 위한 빌드 스크립트를 생성한 Gradle을 사용했습니다 build.gradle. 여기서는 프로젝트에 필요한 종속성을 설명합니다. 종속성은 코드가 없으면 작동할 수 없는 라이브러리입니다. 데이터베이스 연결에 대한 종속성에 대한 설명부터 시작하겠습니다. JDBC로 작업하는 경우와 동일한 방식으로 이 작업을 수행합니다.

dependencies {
	implementation 'com.h2database:h2:1.4.199'
이제 데이터베이스가 생겼습니다. 이제 Java 개체를 데이터베이스 개념(Java에서 SQL로)에 매핑하는 역할을 담당하는 계층을 애플리케이션에 추가할 수 있습니다. 우리가 기억하는 것처럼, 우리는 이를 위해 Hibernate라는 JPA 사양 구현을 사용할 것입니다.

dependencies {
	implementation 'com.h2database:h2:1.4.199'
	implementation 'org.hibernate:hibernate-core:5.4.2.Final'
이제 JPA를 구성해야 합니다. 사양과 "8.1 지속성 단위" 섹션을 읽으면 지속성 단위가 구성, 메타데이터 및 엔터티의 일종의 조합이라는 것을 알 수 있습니다. JPA가 작동하려면 구성 파일에 지속성 단위(Persistence Unit)를 하나 이상 설명해야 합니다 persistence.xml. 해당 위치는 사양 장 "8.2 지속성 단위 패키징"에 설명되어 있습니다. 이 섹션에 따르면 Java SE 환경이 있는 경우 이를 META-INF 디렉토리의 루트에 배치해야 합니다.
JPA: 기술 소개 - 6
" " 장의 JPA 사양에 제공된 예제의 내용을 복사해 보겠습니다 8.2.1 persistence.xml file.
<persistence>
	<persistence-unit name="JavaRush">
        <description>Persistence Unit For test</description>
        <class>hibernate.model.Category</class>
        <class>hibernate.model.Topic</class>
    </persistence-unit>
</persistence>
그러나 이것만으로는 충분하지 않습니다. JPA 제공자가 누구인지 알려줘야 합니다. JPA 사양을 구현하는 사람:
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
이제 설정( )을 추가해 보겠습니다 properties. 그 중 일부( 로 시작 javax.persistence)는 표준 JPA 구성이며 "8.2.1.9 속성" 섹션의 JPA 사양에 설명되어 있습니다. 일부 구성은 제공자별로 다릅니다(우리의 경우 Jpa 제공자로서 Hibernate에 영향을 미칩니다. 설정 블록은 다음과 같습니다:
<properties>
    <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
    <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE" />
    <property name="javax.persistence.jdbc.user" value="sa" />
    <property name="javax.persistence.jdbc.password" value="" />
    <property name="hibernate.show_sql" value="true" />
    <property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
이제 JPA 호환 구성이 있고 persistence.xmlJPA 공급자인 Hibernate와 H2 데이터베이스가 있고 도메인 모델인 2개의 클래스도 있습니다. 마침내 이 모든 것이 작동하도록 합시다. 카탈로그에서 /test/javaGradle은 친절하게도 단위 테스트용 템플릿을 생성하고 이를 AppTest라고 불렀습니다. 그것을 사용하자. JPA 사양의 "7.1 지속성 컨텍스트" 장에 명시된 대로 JPA 세계의 엔터티는 지속성 컨텍스트라는 공간에 있습니다. 그러나 우리는 지속성 컨텍스트를 사용하여 직접 작업하지 않습니다. Entity Manager이를 위해 "엔티티 관리자"를 사용합니다 . 맥락과 거기에 어떤 실체가 살고 있는지 아는 사람은 바로 그 사람입니다. 우리는 '옴'과 상호작용합니다 Entity Manager. 그렇다면 남은 것은 우리가 이것을 어디서 얻을 수 있는지 이해하는 것입니다 Entity Manager. JPA 사양의 "7.2.2 애플리케이션 관리 엔터티 관리자 얻기" 장에 따르면 EntityManagerFactory. 따라서 JPA 사양으로 무장하고 "7.3.2 Java SE 환경에서 Entity Manager 팩토리 얻기" 장의 예를 들어 간단한 단위 테스트 형식으로 지정해 보겠습니다.
@Test
public void shouldStartHibernate() {
	EntityManagerFactory emf = Persistence.createEntityManagerFactory( "JavaRush" );
	EntityManager entityManager = emf.createEntityManager();
}
이 테스트에서는 이미 "인식할 수 없는 JPA persistence.xml XSD 버전" 오류가 표시됩니다. 그 이유는 persistence.xml"8.3 persistence.xml 스키마" 섹션의 JPA 사양에 명시된 대로 사용할 스키마를 올바르게 지정해야 하기 때문입니다.
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
             version="2.2">
또한 요소의 순서도 중요합니다. 따라서 provider클래스를 나열하기 전에 이를 지정해야 합니다. 그러면 테스트가 성공적으로 실행됩니다. 직접 JPA 연결을 완료했습니다. 계속 진행하기 전에 나머지 테스트에 대해 생각해 보겠습니다. 각 테스트에는 EntityManager. EntityManager실행 시작 시 각 테스트에 고유한 테스트가 있는지 확인하겠습니다 . 또한 우리는 데이터베이스가 매번 새로워지기를 원합니다. inmemory옵션을 사용한다는 사실 때문에 닫는 것만으로도 충분합니다 EntityManagerFactory. 창조 Factory는 비용이 많이 드는 작업입니다. 그러나 테스트에서는 정당화됩니다. JUnit을 사용하면 각 테스트 실행 이전(Before)과 이후(After)에 실행될 메서드를 지정할 수 있습니다.
public class AppTest {
    private EntityManager em;

    @Before
    public void init() {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory( "JavaRush" );
        em = emf.createEntityManager();
    }

    @After
    public void close() {
        em.getEntityManagerFactory().close();
        em.close();
    }
이제 테스트를 실행하기 전에 새 데이터베이스가 생성되므로 EntityManagerFactory새 데이터베이스가 생성됩니다. hibernate.hbm2ddl.auto의 의미가 있습니다 create. 그리고 새 공장에서 우리는 새 공장을 얻게 될 것입니다 EntityManager.
JPA: 기술 소개 - 7

엔터티

우리가 기억하는 것처럼, 우리는 이전에 도메인 모델을 설명하는 클래스를 만들었습니다. 우리는 이것이 우리의 "본질"이라고 이미 말했습니다. 이는 우리가 를 사용하여 관리할 엔터티입니다 EntityManager. 카테고리의 본질을 저장하는 간단한 테스트를 작성해 보겠습니다.
@Test
public void shouldPersistCategory() {
	Category cat = new Category();
	cat.setTitle("new category");
	// JUnit обеспечит тест свежим EntityManager'ом
	em.persist(cat);
}
하지만 이 테스트는 바로 작동하지 않을 것입니다. 왜냐하면... 엔터티가 무엇인지 이해하는 데 도움이 되는 다양한 오류가 발생합니다.
  • Unknown entity: hibernate.model.Category
    Category왜 Hibernate는 이것이 무엇인지 이해하지 못합니까 entity? 중요한 것은 엔터티가 JPA 표준에 따라 설명되어야 한다는 것입니다. JPA 사양의 "2.1 엔터티 클래스" 장에 설명된 대로
    엔터티 클래스에 주석을 달아야 합니다 .@Entity

  • No identifier specified for entity: hibernate.model.Category
    엔터티에는 한 레코드를 다른 레코드와 구별하는 데 사용할 수 있는 고유 식별자가 있어야 합니다.
    JPA 사양의 "2.4 기본 키 및 엔터티 ID" 장에 따르면 "모든 엔터티에는 기본 키가 있어야 합니다", 즉 모든 엔터티에는 "기본 키"가 있어야 합니다. 이러한 기본 키는 주석으로 지정되어야 합니다.@Id

  • ids for this class must be manually assigned before calling save()
    ID는 어딘가에서 나와야 합니다. 수동으로 지정하거나 자동으로 얻을 수 있습니다.
    따라서 "11.2.3.3 생성된 값" 및 "11.1.20 생성된 값 주석" 장에 표시된 대로 주석을 지정할 수 있습니다 @GeneratedValue.

따라서 카테고리 클래스가 엔터티가 되려면 다음과 같이 변경해야 합니다.
@Entity
public class Category {
    @Id
    @GeneratedValue
    private Long id;
또한 주석은 @Id어떤 주석을 사용할지 나타냅니다 Access Type. JPA 사양의 "2.3 액세스 유형" 섹션에서 액세스 유형에 대해 자세히 알아볼 수 있습니다. 아주 짧게 말하자면, 왜냐면... @Id필드( ) 위에 지정한 경우 액세스 유형은 가 아닌 field기본값이 됩니다 . 따라서 JPA 제공자는 필드에서 직접 값을 읽고 저장합니다. getter 위에 배치하면 액세스가 사용됩니다. 게터와 세터를 통해. 테스트를 실행할 때 어떤 요청이 데이터베이스로 전송되는지도 확인할 수 있습니다(옵션 덕분에 ). 하지만 저장할 때 '가 표시되지 않습니다 . 우리가 실제로 아무것도 저장하지 않은 것으로 밝혀졌습니다. JPA를 사용하면 다음 메소드를 사용하여 지속성 컨텍스트와 데이터베이스를 동기화할 수 있습니다 . field-basedproperty-based@Idproperty-basedhibernate.show_sqlinsertflush
entityManager.flush();
그러나 지금 실행하면 오류가 발생합니다: no transaction is in Progress . 이제 JPA가 트랜잭션을 어떻게 사용하는지 알아볼 차례입니다.
JPA: 기술 소개 - 8

JPA 트랜잭션

우리가 기억하는 것처럼 JPA는 지속성 컨텍스트 개념을 기반으로 합니다. 이곳은 실체가 사는 곳입니다. 그리고 우리는 를 통해 엔터티를 관리합니다 EntityManager. 명령을 실행할 때 persist엔터티를 컨텍스트에 배치합니다. EntityManager보다 정확하게는 'y에게 이것이 완료되어야 한다고 말합니다 . 하지만 이 컨텍스트는 단지 일부 저장 영역일 뿐입니다. 때로는 "1차 레벨 캐시"라고도 합니다. 하지만 데이터베이스에 연결되어야 합니다. 이전에 오류로 인해 실패한 명령은 flush지속성 컨텍스트의 데이터를 데이터베이스와 동기화합니다. 그러나 이를 위해서는 운송이 필요하며 이 운송은 거래입니다. JPA의 트랜잭션은 사양의 "7.5 트랜잭션 제어" 섹션에 설명되어 있습니다. JPA에서 트랜잭션을 사용하기 위한 특별한 API가 있습니다.
entityManager.getTransaction().begin();
entityManager.getTransaction().commit();
테스트 전후에 실행되는 코드에 트랜잭션 관리를 추가해야 합니다.
@Before
public void init() {
	EntityManagerFactory emf = Persistence.createEntityManagerFactory( "JavaRush" );
	em = emf.createEntityManager();
	em.getTransaction().begin();
}
@After
public void close() {
	if (em.getTransaction().isActive()) {
		em.getTransaction().commit();
        }
	em.getEntityManagerFactory().close();
	em.close();
}
추가한 후에는 삽입 로그에서 이전에는 없었던 SQL 표현식을 볼 수 있습니다.
JPA: 기술 소개 - 9
EntityManager트랜잭션 에서 누적된 변경 사항은 데이터베이스에 커밋(확인 및 저장)되었습니다. 이제 우리의 본질을 찾으려고 노력합시다. ID로 엔터티를 검색하는 테스트를 만들어 보겠습니다.
@Test
public void shouldFindCategory() {
	Category cat = new Category();
	cat.setTitle("test");
	em.persist(cat);
	Category result = em.find(Category.class, 1L);
	assertNotNull(result);
}
이 경우 이전에 저장한 엔터티를 받게 되지만 로그에 SELECT 쿼리는 표시되지 않습니다. 그리고 모든 것은 "엔티티 관리자님, ID=1인 카테고리 엔터티를 찾아주세요."라는 우리의 말을 기반으로 합니다. 그리고 엔터티 관리자는 먼저 해당 컨텍스트(일종의 캐시 사용)를 살펴보고, 찾지 못한 경우에만 데이터베이스를 살펴봅니다. ID를 2로 변경할 가치가 있으며(그런 것은 없으며 인스턴스 1개만 저장했습니다) SELECT요청이 나타나는 것을 볼 수 있습니다. 컨텍스트에서 엔터티를 찾을 수 없고 EntityManager데이터베이스가 엔터티를 찾으려고 하기 때문에 컨텍스트에서 엔터티의 상태를 제어하는 ​​데 사용할 수 있는 다양한 명령이 있습니다. 엔터티가 한 상태에서 다른 상태로 전환되는 것을 엔터티의 수명 주기라고 합니다 lifecycle.
JPA: 기술 소개 - 10

엔터티 수명주기

엔터티의 수명 주기는 "3.2 엔터티 인스턴스의 수명 주기" 장의 JPA 사양에 설명되어 있습니다. 왜냐하면 엔터티는 컨텍스트에 살고 에 의해 제어됩니다 EntityManager. 그런 다음 엔터티가 제어된다고 말합니다. 관리. 엔터티의 삶의 단계를 살펴 보겠습니다.
// 1. New or Transient (временный)
Category cat = new Category();
cat.setTitle("new category");
// 2. Managed or Persistent
entityManager.persist(cat);
// 3. Транзакция завершена, все сущности в контексте detached
entityManager.getTransaction().begin();
entityManager.getTransaction().commit();
// 4. Сущность изымаем из контекста, она становится detached
entityManager.detach(cat);
// 5. Сущность из detached можно снова сделать managed
Category managed = entityManager.merge(cat);
// 6. И можно сделать Removed. Интересно, что cat всё равно detached
entityManager.remove(managed);
이를 통합하는 다이어그램은 다음과 같습니다.
JPA: 기술 소개 - 11
JPA: 기술 소개 - 12

매핑

JPA에서는 엔터티 간의 관계를 설명할 수 있습니다. 도메인 모델을 다룰 때 이미 서로 간의 엔터티 관계를 살펴봤다는 것을 기억해 봅시다. 그런 다음 Quickdatabasediagrams.com 리소스를 사용했습니다 .
JPA: 기술 소개 - 13
엔터티 간의 연결 설정을 매핑 또는 연결(Association Mappings)이라고 합니다. JPA를 사용하여 설정할 수 있는 연결 유형은 다음과 같습니다.
JPA : 기술개론 - 14
Topic주제를 설명하는 엔터티를 살펴보겠습니다 . Topic에 대한 태도에 대해 무엇을 말할 수 있습니까 Category? 많은 사람들이 Topic하나의 범주에 속할 것입니다. 그러므로 협회가 필요합니다 ManyToOne. JPA에서 이 관계를 표현해 보겠습니다.
@ManyToOne
@JoinColumn(name = "category_id")
private Category category;
어떤 주석을 넣을지 기억하려면 마지막 부분이 주석이 표시된 위의 필드를 담당한다는 점을 기억하면 됩니다. ToOne- 특정 인스턴스. ToMany- 컬렉션. 이제 우리의 연결은 단방향입니다. 양방향 의사소통을 해보자. 이 범주에 포함된 Category모든 사람에 대한 지식을 추가해 보겠습니다 . 목록이 있으므로 Topic로 끝나야 합니다 . 즉, "많은"주제에 대한 태도입니다. 질문은 남아 있습니다 - 또는 : ToManyTopicOneToManyManyToMany
JPA: 기술 소개 - 15
동일한 주제에 대한 좋은 답변은 여기에서 읽을 수 있습니다: " ORM oneToMany, ManyToMany 관계를 I'm five처럼 설명하세요 ." 카테고리가 주제와 연결되어 있는 경우 이러한 각 주제는 하나의 카테고리만 가질 수 있으며, 그렇지 않으면 ToMany이 됩니다 . 따라서 모든 주제 목록은 다음과 같습니다. OneManyCategory
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "topic_id")
private Set<Topic> topics = new HashSet<>();
Category그리고 모든 주제의 목록을 얻으려면 기본적으로 getter를 작성하는 것을 잊지 마십시오 .
public Set<Topic> getTopics() {
	return this.topics;
}
양방향 관계는 자동으로 추적하기가 매우 어렵습니다. 따라서 JPA는 이 책임을 개발자에게 전가합니다. 이것이 우리에게 의미하는 바는 와 엔터티 Topic관계를 설정할 때 Category데이터 일관성을 스스로 보장해야 한다는 것입니다. 이는 간단하게 수행됩니다.
public void setCategory(Category category) {
	category.getTopics().add(this);
	this.category = category;
}
확인하기 위한 간단한 테스트를 작성해 보겠습니다.
@Test
public void shouldPersistCategoryAndTopics() {
	Category cat = new Category();
	cat.setTitle("test");
	Topic topic = new Topic();
	topic.setTitle("topic");
	topic.setCategory(cat);
 	em.persist(cat);
}
매핑은 완전히 별개의 주제입니다. 이 검토의 일환으로 이것이 달성되는 수단이 무엇인지 이해할 가치가 있습니다. 매핑에 대한 자세한 내용은 여기에서 확인할 수 있습니다.
JPA : 기술개론 - 16

JPQL

JPA는 Java Persistence Query Language의 쿼리라는 흥미로운 도구를 도입합니다. 이 언어는 SQL과 유사하지만 SQL 테이블이 아닌 Java 객체 모델을 사용합니다. 예를 살펴보겠습니다:
@Test
public void shouldPerformQuery() {
	Category cat = new Category();
	cat.setTitle("query");
	em.persist(cat);
	Query query = em.createQuery("SELECT c from Category c WHERE c.title = 'query'");
 	assertNotNull(query.getSingleResult());
}
보시다시피 쿼리에서는 테이블 Category이 아닌 엔터티에 대한 참조를 사용했습니다. 그리고 이 실체의 분야에서도요 title. JPQL은 많은 유용한 기능을 제공하며 자체 기사를 작성할 가치가 있습니다. 자세한 내용은 리뷰에서 확인할 수 있습니다.
JPA : 기술개론 - 17

기준 API

마지막으로 Criteria API에 대해 살펴보겠습니다. JPA는 동적 쿼리 작성 도구를 도입합니다. 기준 API 사용 예:
@Test
public void shouldFindWithCriteriaAPI() {
	Category cat = new Category();
	em.persist(cat);
	CriteriaBuilder cb = em.getCriteriaBuilder();
	CriteriaQuery<Category> query = cb.createQuery(Category.class);
	Root<Category> c = query.from(Category.class);
	query.select(c);
	List<Category> resultList = em.createQuery(query).getResultList();
	assertEquals(1, resultList.size());
}
이 예는 " " 요청을 실행하는 것과 동일합니다 SELECT c FROM Category c. Criteria API는 강력한 도구입니다. 자세한 내용은 여기에서 읽어보세요.

결론

보시다시피 JPA는 수많은 기능과 도구를 제공합니다. 각각은 경험과 지식이 필요합니다. JPA 검토의 틀 안에서도 상세한 다이빙은 말할 것도 없고 모든 것을 언급하는 것은 불가능했습니다. 하지만 이 책을 읽고 나면 ORM과 JPA가 무엇인지, 어떻게 작동하는지, 그리고 ORM으로 무엇을 할 수 있는지가 더 명확해졌기를 바랍니다. 글쎄, 나는 간식으로 다양한 재료를 제공합니다. #비아체슬라프
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION