JPA

1-2. JPA애플리케이션 개발

희구 2021. 7. 30. 00:39

Hello JPA - 애플리케이션 개발

 

JPA 구동 방식

1. jpa는 Persistence파일에서 시작을 한다.

2. 여기서 설정정보를 읽어서 EntityManagerFactory라는 클래스를 생성함

3. 여기에서 필요할때 마다 EntityManager를 찍어내서 동작함

 

 


실습 - JPA 동작 확인

- JPAMain 클래스 생성

- JPA 동작 확인

 

JPAMain 클래스 생성

persistenceUnitName을 넘기라고 한다.

이건 바로 persistence.xml  파일에 설정해줬던 unit name이다.

 

unitName 설정

createEntityManagerFactory에 커서를 놓고 Ctrl+Alt+V 로 변수를 받는다.

entityManagerFactory를 받는데 너무 길어서 emf로 줄여서 쓸 거다.

EntityManagerFactory를 만드는 순간 데이터베이스와 연결이 된 것이다.

 

EntityManagerFactory에서 createEntityManager를 꺼낸다.

꺼내고 여기서 우리가 코드를 작성하고

실제 애플리케이션이 완전히 끝나면 끝나면 EntityManagerFactory를 닫아준다.

 


객체와 테이블을 생성하고 매핑하기

 

1. DB에 Member 테이블 만들기

테이블을 만들고 매핑을 해봐야 JPA동작을 확인할 수 있기 때문이다.

h2에 접속하는데 여기서 중요한 것이

h2에 접속할 때 쓰이는 JDBC URL과 설정파일(persistence.xml)에 적은 jdbc.url이 동일해야한다.

그리고 사용자명과 비밀번호도 똑같이 맞춰야 한다.

 

Member 테이블 생성
만들어진 테이블 

 

 

 

2. 이 테이블과 매핑되는 클래스 생성

 

@Entity : JPA가 관리할 객체

@Id : 데이터베이스 PK와 매핑

 

Member 클래스

테이블을 생성하면 먼저 @Entity 어노테이션을 반드시 걸어준다.

그래야 이게 JPA로 돌아간다는 걸 알기 때문이다.

db에 있는 id와 name을 만들어주는데 jpa에게 pk값이 어떤건지 알려주어야한다.

그리고 겟터 셋터도 만들어준다.

 

 


 
실제로 돌아가는지 보기 위해 멤버를 저장해보겠다!

어떻게?

EntityManagerFactory는 애플리케이션 로딩 시점에 딱 하나만 만들어놔야한다.

그리고 실제로 디비에 저장하는 것은 매 트렌젝션마다 entityManager를 만들어줘야한다.

 

image-20210729223355835

이렇게 멤버를 넣어주고 돌려보았지만 에러가 난다.

 

왜냐하면?

JPA는 트렌젝션이라는 것이 매우 중요하다.

모든것은 트렌젝션 단위 안에서 작업해야한다.

그래서 우리는 트렌젝션을 만들어 준다.

 

image-20210729223720915

트렌젝션을 생성하고 -> 시작하고 -> 로직을 만들어서 -> jpa에 저장하고 -> 트렌젝션 커밋하고-> 닫아준다.

 

run해보면?

 

image-20210729223811434

콘솔창에 이렇게 쿼리문이 뜬다.

image-20210729223846835

왜냐하면 우리가 설정파일에 이렇게 쿼리문이 보이고, 포멧팅을 해주고, 코멘트까지 나오도록 설정해놨기 때문이다.

image-20210729223926379

그러고 디비에 와보면 이렇게 값이 들어와있다.

 

 

image-20210729224019111

다시 이렇게 아이디와 이름을 바꿔서 런하고 디비에 와보면

image-20210729224043211

이렇게 두번째로 넣어줬던 값도 들어와있다.

 

 

이게바로 JPA가 맵핑 정보를 보고 직접 값을 넣어주는 것이다.

우리가 쿼리문을 작성한 것은 하나도 없다.

 

 

image-20210729224207012

만약 테이블명과 클래스명이 다르다면 이런식으로 써놓으면

디비에 이름이 "USER"인 테이블과 맵핑된다.

 

image-20210729224305126

컬럼명이 다른경우엔 이런식으로 써줌.

 

 

일단 에러없이 잘 동작했지만 위 코드는 안 좋은 코드다.

왜냐하면 tx.commit에서 에러가 났을 때

em.close()와 emf.close()모두 동작하지 못하기 때문이다.

 

 

정석코드

그래서 우리는 try~catch안에다가

문제가 생기면 tx.rollback()해주고

작업이 끝나면 엔티티매니저가 닫아줄 수 있도록 코드를 수정했다.

그리고 전체 애플리케이션이 끝나면 엔티티매니저팩토리도 닫아버렸다.

 


실습

 

조회

 

image-20210729233348378image-20210729233435010

정확히 조회됨

 


삭제

 

image-20210729233546635

삭제는 이렇게 remove라고 쓰고 괄호 안에 찾은 애를 넣어주면

delete쿼리가 작성되면서 삭제된다.

 

 


 

수정

 

image-20210729233806084

 

em.persist()안해줘도 알아서 저장해줌.

image-20210729233941057

콘솔창

 

image-20210729234005254

DB

디비 이름이 HelloA -> HelloJPA로 바뀌어있다.

 

 


 

어떻게 값만 바꿨는데 수정되고 저장되는걸까?

JPA를 통해 엔티티를 가져오면 얘는 제이피에이가 관리를한다.

그리고 JPA가 변경 됫는지 안됏는지 트렌젝션이 커밋하는 시점에 다 체크를한다.

그래서 무언가 바뀐게 잇으면 update쿼리를 만들어서 날리고 커밋한다.

 

주의점!

엔티티 매니저 팩토리하나만 생성해서 애플리케이션 전체에서 공유

엔티티 매니저쓰레드간에 공유X (필요할 때 마다 생성해서 사용하고 버려야 한다).

JPA의 모든 데이터 변경은 트랜잭션 안에서 실행

 

 


JPQL 소개

  • 가장 단순한 조회방법이다.
  • 나이가 18살 이상인 회원을 모두 검색하고 싶다면? 이럴때 JPQL을 사용한다..
  • 수십-수백개의 테이블에서 내가 원하는 데이터를 쉽게 가져오기 위해 JPA에서 JPQL이라는 것으로 도와준다.
  • 객체를 대상으로 하는 객체지향 쿼리
  • 방언에 맞춰서 각 디비에 맞게 쿼리문을 번역해준다.
  • JPA는 SQL을 추상화한 JPQL이라는 객체지향쿼리언어를 제공한다
  • JPQL은 엔티티 객체를 대상으로 쿼리, SQL은 테이블을 대상으로 쿼리!

예를 들어 Member를 모두 조회하려면. 이런식으로 써주는데

createQuery라고 해서 쿼리문을 직접 작성할 수 있다.

그런데 여기서는 테이블을 조회하는 것이 아니라 객체를 조회하는 것으로

Member객체를 모두 조회한다는 뜻이다.

한 마디로 객체지향 쿼리라는 뜻

 

JPQL

 

이게 왜 좋나?

예를들어 이렇게 짠다고 하면.

페이징할때..

.setFirstResult(1)
.setMaxResults(10)

-> 1페이지 부터 10페이지를 출력해라..

간단하게 출력 할 수 있음

 

 

 

 

 

[출처] 김영한님의 자바 ORM 표준 JPA 프로그래밍 - 기본편

(https://www.inflearn.com/course/ORM-JPA-Basic/dashboard)

'JPA' 카테고리의 다른 글

2-2. 플러시  (0) 2021.08.02
2-1. 영속성 관리  (0) 2021.08.02
1-1. JPA 시작하기  (0) 2021.07.28
JPA 소개  (0) 2021.07.28
JPA란?  (0) 2021.07.28