이 포스팅에서 작성하는 내용은 자바 ORM 표준 JPA 프로그래밍 (김영한 지음) 에서 발췌하였습니다.
1. JPA 구동 방식
1) pesistence라는 클래스가 persistence.xml(설정파일)을 읽어서 EntityManagerFactory라는 클래스를 만든다.
2) EntityManagerFactory에서 EntityManager를 생성한다.
- EntityManagerFactory 는 하나만 생성해서 애플리케이션 전체에서 공유 (싱글톤)
- EntityManager는 쓰레드 간에 공유되지 않음. (사용하고 버려야함)
- JPA의 모든 데이터 변경은 트랜잭션 안에서 실행되야함
2. JPA 구조 설정
1) EntityManagerFactory를 만들어보자.
필자는 아래의 그림처럼 'jpaMain.java'를 생성하였으며,
EntityManagerFactory를 만들 때, 들어가는 인자는 resources/META-INF/persistence.xml의 persistence-unit name을 넣어주면 된다.
package com.sampleJpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class jpaMain {
public static void main(String[] args){
// 아래 들어가는 인자는 resources/META-INF/persistence.xml의 persistence-unit name을 넣어주면 된다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
em.close();
emf.close();
}
}
2) EntityManagerFactory를 생성 및 실행해보자
* 실행 시, javax/xml/bind/JAXBException 오류가 발생하는 경우
Java 11 이상의 사용자들에겐 아마 오류가 발생했을 것이다.
Java 11 이전까지는 JAXB가 기본적으로 포함되어있었는데, 11부터는 따로 추가해줘야 한다고한다.
JAXB? Java Architecture for Xml Binding. xml을 Java Object형식으로 바꿔주는 기술
출처 : https://yoonemong.tistory.com/254
해결 방법 : pom.xml에 아래의 의존성을 추가한다.
<!-- java 11버전부터 xml을 Java Object형식으로 바꿔주는 기술이 default가 아니므로, 넣어줘야함 (jpa Setting을 xml로 함) -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
* Connect time out이 뜨는 경우
H2 데이터베이스를 켜주면 됩니다.
만일 정상적으로 실행된다면, 아래의 캡처처럼 에러없이 잘 나와야 한다.
3. JPA로 MemberInfo 테이블에 데이터 넣기
1) H2 데이터베이스에 샘플 테이블(MemberInfo) 생성
H2 데이터베이스에 아래의 멤버정보 테이블을 만들어주자.
create table memberInfo(
memberId bigint not null,
memberName varchar(100),
primary key(memberId)
);
2) 아래의 소스처럼 MemberInfo 클래스를 정의
필자는 jpaMain 클래스파일과 같은 패키지에 생성하였습니다.
package com.sampleJpa;
import javax.persistence.Entity;
import javax.persistence.Id;
/**
JPA 관련 어노테이션 선언 시,
javax.persistence로 시작하는 패키지를 임포트할 것!!
*/
@Entity
public class MemberInfo {
// @Id : PK라는 의미
@Id
private Long memberId;
private String memberName;
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public Long getMemberId() {
return memberId;
}
public void setMemberId(Long memberId) {
this.memberId = memberId;
}
}
3) jpaMain 클래스에 트랜잭션 로직과 memberInfo를 이용해서 Insert
package com.sampleJpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class jpaMain {
public static void main(String[] args){
// 아래 들어가는 인자는 resources/META-INF/persistence.xml의 persistence-unit name을 넣어주면 된다.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
// em 이 실질적으로 DB조작하는 기능이라고 생각하면 된다.
EntityManager em = emf.createEntityManager();
// 트랜잭션 가져오기
EntityTransaction et = em.getTransaction();
// 트랜잭션 시작
et.begin();
try{
// memberInfo 객체에다가 memberId와 memberName에 값을 설정
// Id에 값을 넣지 않고 실행 시, 오류 발생함 (PK는 값이 있어야 하기 때문)
MemberInfo memberInfo = new MemberInfo();
memberInfo.setMemberId(1L);
memberInfo.setMemberName("firstName");
em.persist(memberInfo);
// 트랜잭션 커밋
et.commit();
} catch (Exception e){
// 오류 발생 시, 트랜잭션 롤백
et.rollback();
} finally {
// 끝나면 EntityManager 꼭 닫아주기
em.close();
}
emf.close();
}
}
아래의 로그처럼 나온다면 정상적으로 Insert가 된 것
* DB에서도 확인해보면 정상적으로 추가되어있는 것을 알 수 있다.
4. MemberInfo 테이블의 데이터를 조회 & 수정 & 삭제
1) 아까 삽입한 데이터 조회하기
jpaUpdateMain이라는 클래스를 새로 하나 선언해서 아래의 소스처럼 작성
package com.sampleJpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.lang.reflect.Member;
public class jpaUpdateMain {
public static void main(String[] args){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
et.begin();
try{
// PK로 MemberInfo 테이블 조회하기.
// PK는 1L
MemberInfo memberInfo = em.find(MemberInfo.class, 1L);
System.out.println("아이디 : " + memberInfo.getMemberId());
System.out.println("이름 : " + memberInfo.getMemberName());
// 커밋
et.commit();
} catch(Exception e){
// 오류 시 롤백
et.rollback();
} finally {
// 작업 종료 할 때, EntityManager 닫는 것 잊지않기!
em.close();
}
emf.close();
}
}
실행 시 아래 처럼 나오면 정상
2) MemberName 수정하기
package com.sampleJpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.lang.reflect.Member;
public class jpaUpdateMain {
public static void main(String[] args){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
et.begin();
try{
// PK로 MemberInfo 테이블 조회하기.
// PK는 1L
MemberInfo memberInfo = em.find(MemberInfo.class, 1L);
System.out.println("아이디 : " + memberInfo.getMemberId());
System.out.println("이름 : " + memberInfo.getMemberName());
// 멤버의 이름을 수정
memberInfo.setMemberName("changed Name");
// 커밋
et.commit();
} catch(Exception e){
// 오류 시 롤백
et.rollback();
} finally {
// 작업 종료 할 때, EntityManager 닫는 것 잊지않기!
em.close();
}
emf.close();
}
}
실행 결과
DB 확인
3) MemberName 삭제하기
jpaDeleteMain이라는 클래스를 새로 하나 선언해서 아래의 소스처럼 작성
package com.sampleJpa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class jpaDeleteMain {
public static void main(String[] args){
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
EntityManager em = emf.createEntityManager();
EntityTransaction et = em.getTransaction();
et.begin();
try{
// PK로 MemberInfo 테이블 조회하기.
// PK는 1L
MemberInfo memberInfo = em.find(MemberInfo.class, 1L);
System.out.println("아이디 : " + memberInfo.getMemberId());
System.out.println("이름 : " + memberInfo.getMemberName());
// 멤버 삭제 (삭제 시에는 EntityManager를 이용함)
em.remove(memberInfo);
// 커밋
et.commit();
} catch(Exception e){
// 오류 시 롤백
et.rollback();
} finally {
// 작업 종료 할 때, EntityManager 닫는 것 잊지않기!
em.close();
}
emf.close();
}
}
실행 결과
DB 확인
'BE > JPA' 카테고리의 다른 글
[JPA] 6. 영속성 컨텍스트란? (0) | 2022.04.11 |
---|---|
[JPA] 5. JPA에서 리스트를 조회해보자 (0) | 2022.04.05 |
[JPA] 3. JPA 프로젝트 세팅 (0) | 2022.03.26 |
[JPA] 2. Java Persistence API 란 (0) | 2022.03.18 |
[JPA] 1. 왜 JPA를 공부해야 할까? (0) | 2022.03.16 |