⬛️ JPA 간단하게 사용해보기

이준영·2023년 9월 13일
0

⬛️ JPA

목록 보기
2/3
post-thumbnail
참고

개인적으로 영한님 강의를 본 후 정리하며 복습하기 위한 글 입니다.


JPA 간단하게 사용해보기

JPA 간단한 동작 과정

JPA는 간단하게 아래와 같은 순서로 동작합니다.

1. 설정 정보 조회

- 데이터베이스 연결 정보, 데이터베이스 Dialect(Mysql인지, Oracle인지) , 엔티티 클래스 종류등을 확인 합니다.

2. EntityManagerFactory 생성

- EntityManagerFactory는 어플리케이션 로딩 시점에 하나만 만들어지고 이후 emf 에서 EntityManager를 생성하여 요청을 처리합니다.

3. EntityManager 생성

- 하나의 작업 단위마다 em을 생성하고 요청을 처리하고 em.close()를 통해 종료해 주어야 합니다.(쓰레드간에 공유 하면 안됨)
⛔️ JPA의 모든 변경은 하나의 트랜잭션 안에서 이루어져야 합니다.
객체를 통해 데이터를 관리하지만, 실제로는 내부에서 쿼리를 날려 DB를 조작하기 때문


객체와 DB 테이블 간단하게 매핑 해보기

@Entity
public class Member {
	@Id 	//PK 가 무엇인지 알려줘야 함
	private Long id;
    
	private String name;
	//Getter, Setter …
}

@Entity를 선언하여 객체와 테이블을 매핑 시킬 수 있습니다. 각 테이블은 PK를 기본적으로 가져야 하기 때문에 @Id 어노테이션을 통해 어떤 변수가 PK값을 의미하는지 표시해 주어야 합니다.

기본적으로 테이블 명은 클래스 이름의 맨 처음을 소문자로 매핑되고, Column의 이름은 필드 변수명으로 매핑되게 됩니다. 만약 이름을 자신이 원하는 형태로 바꾸고 싶다면 @Table, @Column 어노테이션을 통해 수정할 수 있습니다.

@Entity // JPA가 관리하기 위해서는 @Entity를 붙여줘야 함
@Table(name ="USER") // USER 테이블과 매핑
public class Member {

    @Id // PK 가 무엇인지 알려줘야 함
    private Long id;
    
    @Column(name = "username") //Column명 username과 매핑
    private String name;
}
⛔️ 테이블과 컬럼명이 일치하지 않다면 해당 db 테이블(컬럼명)을 찾을 수 없다는 에러가 발생할 수 있습니다.


JPA로 간단하게 CRUD 해보기

위에서 언급했던 것과 같이 JPA는 설정정보를 확인하고, EntityManagerFactory를 로딩 시점에 하나 생성하고 이후 요청마다 EntityManager를 생성하여 요청을 처리하고 em을 종료합니다. 또한 하나의 요청은 하나의 트랜잭션 안에서 이루어져야 하기 때문에 트랜잭션을 실행하고 성공시 커밋 실패시 롤백이 이루어져야 합니다. 이후 em은 반드시 종료되어야 하기에 아래와 같이 기본 세팅을 해 두었습니다.

// 어플리케이션 로딩 시점에 딱 하나만 생성됨
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");

// 하나의 작업 단위마다 em을 생성해서 처리하고 종료하고 해야 함
// 엔티티 매니저는 쓰레드간에 공유해서는 안된다(사용 후 버려야 함)
EntityManager em = emf.createEntityManager();

// JPA의 모든 데이터 변경은 트랜잭션 아래서 실행해야한다.
EntityTransaction tx = em.getTransaction();
tx.begin(); // 트랜잭션 시작

try {
	//요청 처리
    
	tx.commit(); 	//완료 커밋
} catch (Exception e) {
	System.out.println("hi");
	tx.rollback(); // 실패 롤백
} finally {
	em.close();
}

emf.close();

CRUD는 try문 내부 //요청처리 부분에서 이루어 질 것입니다.

생성하기 - persist()

try {
	Member member = new Member();
	member.setId(1L);
	member.setName("MemberA");
	em.persist(member); // 객체 저장
    
    tx.commit();
}
...

em.persist() 를 호출하고 내부 인자로 인스턴스를 전달하면 insert문이 날아가 DB에 값이 저장되는 것을 확인할 수 있습니다.


조회하기 - find()

try {
	Member findMember = em.find(Member.class, 1L)    
    System.out.println("findMember.getName() = " + findMember.getName());
    tx.commit();
}
...

em.persist() 를 호출하고 내부 인자로 반환받을 클래스 타입과, id(PK) 값을 넣어주면 해당하는 데이터를 조회 후 객체로 반환해 줍니다.


수정하기 - dirtychecking

try {
	Member findMember = em.find(Member.class, 1L);
	findMember.setName("MemberHIHIHI");

    tx.commit();
}
...

수정의 경우 실제 자바 컬렉션에서 데이터를 조회 후 수정하면 컬렉션 내부 값이 변경되는 것처럼, 조회한 객체의 데이터의 값을 변경해 주면 commit이 이루어질 때 자동으로 수정이 이루어집니다. 이렇게 수정이 가능 한 이유는 JPA 의 여러가지 기능 중 dirtychecking에 의해 이후 커밋이 이루어질 때 기존상태에서 변경이 일어나면 JPA가 이를 감지해 update문을 날려주기 때문입니다.


삭제하기 - remove()

try {
	Member findMember = em.find(Member.class, 1L);
	em.remove(findMember);

    tx.commit();
}
...

삭제의 경우는 조회한 객체 인스턴스를 em.remove()의 인자로 전달해주면 커밋이 이루어질 때 delete 쿼리도 함께 날아가 지워지게 됩니다.

Spring Data JPA 의 편리한기능을 통해 너무나 마법같이 CRUD 가 가능했지만, 그 내부에서는 이러한 자잘한 여러 코드들이 수행되고 있었다는것을 잊지 말고 감사히 사용하려고 합니다.
profile
작은 걸음이라도 꾸준히

0개의 댓글