스프링 부트 없이 JPA를 설정하는 방법입니다.
1. 프로젝트 생성
(1) Maven project 생성
- JAVA 11 사용
- Maven 선택
- groupId: jpa-basic
- artifactId: ex1-hello-jpa
- version: 1.00
(2) 라이브러리 추가 - pom.xml
<dependencies>
<!-- JPA 하이버네이트 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.3.13.Final</version>
</dependency>
<!-- H2 데이터베이스 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.199</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
- hibernate 5.3.13 버전 사용
- JPA 표준과 하이버네이트를 포함하는 라이브러리
- hibernate-entitymanager를 라이브러리로 지정하면
- hibernate-core.jar
- hibernate-jpa-2.1-api.jar 라이브러리도 함께 내려받는다.
- 데이터베이스는 h2 1.4.199 버전 사용
- 자신이 사용한 h2 데이터베이스 버전에 맞춰줘야 한다.
- 자바 11을 사용하는 경우 java.xml.bind를 추가해주어야 한다.
자바 11부터는 해당 라이브러리가 자바 기본에서 빠져있어 이와 같은 에러 발생 가능.
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
2. JPA 설정하기
(1) persistence.xml
- JPA 설정 파일
- 파일 위치
- src/main
- java
- resources
- META_INF
- persistence.xml
- META_INF
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
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">
<persistence-unit name="hello">
<properties>
<!-- 필수 속성 -->
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.user" value="sa"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<!-- 옵션 -->
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.use_sql_comments" value="true"/>
<!-- <property name="hibernate.hbm2ddl.auto" value="create" />-->
</properties>
</persistence-unit>
</persistence>
- pom.xml에 설정하였던 persistence-unit name 이름을 지정한다.
- 일반적으로 연결할 데이터베이스당 하나의 영속성 유닛을 등록한다.
- javax.persistence.jdbc.driver : JDBC 드라이버
- javax.persistence.jdbc.user : 데이터베이스 접속 아이디
- javax.persistence.jdbc.password : 데이터베이스 접속 비밀번호
- javax.persistence.jdbc.url : 데이터베이스 접속 URL
- hibernate.show_sql : 하이버네이트가 실행한 SQL을 출력한다.
- hibernate.format_sql : 하이버네이트가 실행한 SQL을 출력할 때 보기 쉽게 정렬한다.
- hibernate.use_sql_comments : 쿼리를 출력할 때 주석도 함께 출력한다.
(2) 데이터베이스 방언
- JPA는 특정 데이터베이스에 종속되지 않는다.
- 각각의 데이터베이스가 제공하는 SQL 문법과 함수는 조금씩 다르다.
- 방언 : SQL 표준을 지키지 않는 특정 데이터베이스만의 고유한 기능
- 하이버네이트는 40가지 이상의 데이터베이스 방언을 지원한다.
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle8iDialect"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
3. JPA 구동 방식
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;
public class JpaMain {
public static void main(String[] args) {
//Database 하나당 묶여서 돌아간다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
//고객이 요청이 올때마다 생성
EntityManager em = emf.createEntityManager();
//JPA data 모든 변경은 transaction 안에서 일어나야 한다.
EntityTransaction tx = em.getTransaction();
tx.begin();
...
tx.commit();
} catch (Exception e) {
tx.rollback();
} finally {
em.close();
}
emf.close();
}
}
(1) EntityMangerFactory 생성
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
- JPA를 시작하려면 우선 persistence.xml의 설정 정보를 사용해서 엔티티 매니저 팩토리를 생성해야 한다.
- META-INF/persistence.xml에서 이름이 jpabook인 영속성 유닛(persistence-unit)을 찾아서 엔티티 매니저 팩토리를 생성한다.
- 엔티티 매니저 팩토리는 애플리케이션 전체에서 딱 한 번만 생성하고 공유해서 사용해야 한다.
(2) EntityManger 생성
EntityManager em = emf.createEntityManager();
- JPA의 기능 대부분은 엔티티 매니저가 제공한다.
- 엔티티 매니저를 사용해서 엔티티를 데이터베이스에 등록/수정/삭제/조회할 수 있다.
- 엔티티 매니저는 내부에 데이터베이스 커넥션을 유지하면서 데이터베이스와 통신한다.
- 엔티티 매니저는 데이터베이스 커넥션과 밀접한 관계가 있으므로 스레드 간에 공유하거나 재사용하면 안 된다.
(3) 종료
em.close();
emf.close();
- 사용이 끝난 엔티티 매니저는 반드시 종료해야 한다.
- 애플리케이션을 종료할 때 엔티티 매니저 팩토리도 종료해야 한다.
(4) EntityTransaction 관리
EntityTransaction tx = em.getTransaction();
tx.begin();
tx.commit();
- JPA를 사용하면 항상 트랜잭션 안에서 데이터를 변경해야 한다.
- 트랜잭션 없이 데이터를 변경하면 예외가 발생한다.
- 엔티티 매니저에서 트랜잭션 API를 받아와야 한다.
4. JPA를 이용한 CRUD
- 등록, 수정, 삭제, 조회 작업은 엔티티 매니저를 통해서 수행된다.
//객체 생성
Member member = new Member();
member.setName("helloA");
//Create
em.persist(member);
//한 건 조회, Read
Member findMember = em.find(Member.class, 1L);
System.out.println(findMember.getId()); // 1
System.out.println(findMember.getName()); // "helloA"
//Update
Member updateMember = em.find(Member.class, 1L);
updateMember.setName("helloJPA");
//Delete
Member deleteMember = em.find(Member.class, 1L);
em.remove(deleteMember);
//목록 조회, Read (JPQL)
List<Member> result = em.createQuery("select m from Member as m", Member.class).getResultList();
for (Member mem : result) {
System.out.println("member.getName() = " + mem.getName());
}
(1) Create
em.persist(member);
- 엔티티를 저장하려면 엔티티 매니저의 persist() 메서드에 저장할 엔티티를 넘겨주면 된다.
(2) Read
//1개 조회
Member findMember = em.find(Member.class, 1L);
//목록 조회 (JPQL)
List<Member> result = em.createQuery("select m from Member as m", Member.class) .getResultList();
- find()를 이용하면 SELECT SQL을 생성하고 실행할 수 있다.
- 필요한 데이터만 데이터베이스에서 불러오려면 결구 검색 조건이 포함된 SQL을 사용해야 한다.
- JPA는 JPQL(Java Persistence Query Language) 제공
* SQL vs JPQL
- SQL은 데이터베이스 테이블을 대상으로 쿼리한다.
- JPQL은 엔티티 객체를 대상으로 쿼리한다.
- from Member는 회원 엔티티 객체를 뜻한다. JPQL은 데이터베이스 테이블을 전혀 알지 못한다.
(3) Update
updateMember.setName("helloJPA");
- 단순히 엔티티의 값만 변경하면 JPA가 어떤 엔티티가 변경되었는지 추적하여서 UPDATE SQL을 생성하고 실행된다.
(4) Delete
em.remove(deleteMember);
- DELETE SQL을 생성해서 실행된다.
반응형
'JPA > JPA' 카테고리의 다른 글
[JPA] 상속 관계 매핑 (0) | 2022.01.03 |
---|---|
[JPA] 연관관계 매핑 - 2 (0) | 2022.01.02 |
[JPA] 연관관계 매핑 - 1 (0) | 2022.01.01 |
[JPA] 엔티티 매핑 (Entity Mapping) (0) | 2021.12.31 |
[JPA] 영속성 컨텍스트 (Persistence context) (0) | 2021.12.29 |
댓글