java, spring

JPA 맛보기

isaac.kim 2022. 6. 10. 21:43
728x90
반응형

JPA 맛보기

이번 글은 프로젝트에 JPA 도입을 위해 JPA에 대해 기초 학습한 내용 및 보충한 글이다. 해당 글은 김영한 님의 JPA 기본 편 강의 앞부분을 듣고 공부한 것을 작성한 내용이다.

 

목차

1. JPA

2. 객체와 RDB

3. JPA 동작

4. JPA를 왜 사용해야 하는가?

5. JPA 프로젝트

6. JPQL

 

 

반응형

 


1. JPA

JPA는 Java Persistence API의 약자이고, JAVA 진영의 ORM 기술 표준이다. ORM은 Object Relational Mapping의 약자이고, 객체와 관계형 데이터베이스를 맵핑해주는 것을 말한다.

 

1) JPA의 장점

- 생산성 증가

- 유지보수성 향상

- SQL 노가다 횟수가 확연히 줄어든다.

 

2) JPA 사용 주의사항

※ 객체와 Table을 제대로 설계하는 것이 중요하여 제대로 설계하는 방법을 학습해야 한다.

 

3) 왜 JPA 인가

장점이 말을 다 해주고 있다.

 

자세히...

 

지금 시대는 객체를 관계형 데이터베이스에 저장하고 관리하고 있다. 또한, 객체 지향 언어를 사용하고 있지만 SQL 중심적인 개발을 하고 있다.Table 하나 생성하면 CRUD를 작성해야 하고, Java를 SQL로, SQL을 Java 객체로 만드는 번거로운 작업을 해야 한다. 예를 들어, DB Table에 Column이 하나 추가되면, 관련 모든 SQL을 모두 수정해야 한다. 결국 SQL에 의존적인 개발을 피하기 어렵다.

 

위와 같은 단순한 이유를 넘어서 애초에 객체와 관계형 데이터베이스의 패러다임은 불일치 하다는 것이다. 그렇기 때문에 SQL에 의존적인 개발을 할 수밖에 없게 된 것이다.

 

그런 패러다임의 불일치를 해결할 수 있는 것이 JPA이다. 그래서 선택한다.

 

 

 

2. 객체와 RDB

'객체 vs 관계형 데이터베이스' 둘은 어떻게 다른지 확인해보자.

 

먼저 객체, 객체 지향 프로그래밍은 추상화, 캡슐화, 정보은닉, 상속, 다형성 등의 특징을 갖고 있다. 반면 관계형 데이터베이스는 테이블에 데이터를 잘 보관하기 위한 구조지, 객체의 특성을 갖지는 않는다.

 

객체와 관계형 데이터베이스를 비교해보고, 왜 SQL중심적인 개발이 되고 문제점이 있는지 확인해보자.

 

 

상속

객체의 상속을 관계형 데이터베이스에서는 Super-Type Sub-Type Relationship으로 테이블을 표현하면 둘을 비슷하게 볼 수 있다.

자식 테이블들은 부모 테이블의 기본 키를 받아서 사용하는 '기본 키 + 외래 키'를 사용하게 된다. 조회할 때면 조인을 사용해야 한다. 객체는 타입에 따라 구분되지만, 테이블의 데이터는 타입 구분이 없다. 따라서, DB의 부모 테이블에는 타입을 구분하는 컬럼을 추가해야 한다.

 

조회할 때는 조인 쿼리, 등록할 때는 2개의 테이블에 insert 쿼리문을 작성해야 한다.

 

 

연관관계

객체는 한 방향으로 접근을 하고, Table은 JOIN을 통해 외래 키로 양방향 접근이 가능하다. 객체는 역방향 참조를 할 수 없다.

 

 

객체 그래프 탐색

객체는 자유롭게 객체 그래프를 탐색할 수 있어야 한다.

 

객체는 객체 지향적으로 설계하고 사용할 수 있지만

실제로 객체 지향적으로 설계할수록 작성해야 하는 SQL이 늘어난다.

그럼 뭐다? -> SQL 노예

 

 

이러한 부분을 해결해주겠다고 나온 것이 JPA ORM이다.

 

※ ORM

Object-relational mapping(객체 관계 매핑)

객체는 객체대로 설계

관계형 데이터베이스는 관계형 데이터베이스대로 설계

ORM 프레임워크가 중간에서 매핑 (대중적인 언어에는 대부분 ORM 기술이 존재)

 

 

3. JPA 동작

JPA 동작 - 저장

김영한님의 jpa 기본편 강의 캡처 이미지

JPA 동작 - 조회

김영한님의 jpa 기본편 강의 캡처 이미지

여기서 중요한 것은 JPA가 패러다임의 불일치를 해결한다는 것이다.

 

 

4. JPA를 왜 사용해야 하는가?

- SQL 중심적인 개발에서 객체 중심으로 개발

- 생산성

- 유지보수

- 패러다임의 불일치 해결

- 성능

- 데이터 접근 추상화와 벤더 독립성

- 표준

 

 

JPA생산성을 보자. CRUD는 다음 메서드 한 줄로 작성하면 된다. 그리고 필드가 추가되어도 쿼리를 수정할 필요가 없다.

김영한님의 jpa 기본편 강의 캡처 이미지

JPA를 사용해 객체와 관계형 데이터베이스의 패러다임의 불일치를 해결할 수 있다.

김영한님의 jpa 기본편 강의 캡처 이미지

상속되는 객체에 데이터를 저장할 때, 테이블에 데이터를 저장하기 위해 INSERT SQL을 개발자가 두 번 작성해야 했는데, JPA에서 알아서 INSERT SQL을 두 번 작성해 처리한다.

 

조회의 경우에도 상속으로 엮인 객체를 조회하기 위해 SELECT JOIN SQL을 작성해야 하는데, JPA가 이를 대신 작성한다.

김영한님의 jpa 기본편 강의 캡처 이미지

 

연관관계에 저장을 한다거나, 객체의 그래프 탐색 또한 JPA가 처리를 해주어서 신뢰할 수 있는 엔티티와 계층을 이룰 수 있다.

김영한님의 jpa 기본편 강의 캡처 이미지

 

JPA는 트랜잭션과 캐싱 지원한다.

김영한님의 jpa 기본편 강의 캡처 이미지

옵션 하나로 지연 로딩, 즉시 로딩을 컨트롤할 수 있다.

 

 

5. JPA 프로젝트

 

필요한 라이브러리는 다음과 같다. 

- JPA-Hibernate

- Database Driver

 

필수 설정 파일 : persistence.xml

속성 및 옵션 설정, Dialect 방언 설정

 

JPA 구동 방식은 다음과 같다.

 

 

실제 동작을 위한 클래스 구성 확인하기

 

기본 구성 소스코드는 다음과 같다.

1. JpaMain 클래스 생성

2. 기본 틀을 위한 code 작성

*EntityManagerFactory는 로딩 시점에 딱 하나만 만들어야 한다.

*EntityManager는 한 트랜잭션 단위에 하나 생성해서 사용한다.

*트랜잭션 단위 코드를 작성한다.

*EntityManagerFactory, EntityManager닫고 종료되어야 한다.

3. JPA 동작 확인

 

 

Entity

@Entity 어노테이션이 있어야 JPA에서 관리한다고 인식한다.

@Id 어노테이션은 최소 PK를 지정한다.

 

테이블이나, 칼럼 명칭이 다른 경우에는

@Table(name="실제테이블명"), @Column(name="실제컬럼명")

어노테이션으로 맵핑하여 사용한다.

 

 

다시,

JPA 동작 확인하기

JPA는 무조건 트랜잭션 단위로 동작한다.

 

 

 

정석 코드(예외처리 추가)

실제 Spring 에서는 Persist만 작성하면 된다. 다른 작업은 Spring에서 처리한다.

자바 객체에서 변경만 했는데도 update query를 날린다.

 

주의

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

- 엔티티 매니저는 스레드 간에 공유하지 않는다. 사용 후 닫아야 한다.

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

 

 

6. JPQL

가장 단순한 조회 방법
 - EntityManager.find()
 - 객체 그래프 탐색(a.getB().getC())
나이가 18살 이상인 회원을 모두 검색하고 싶다면?

SQL에서 WHERE을 사용한다고 할 때 JPQL을 사용한다.

 

JPQL 맛보기

JPQL은 SQL에서 TABLE을 대상으로 하는 것이 아니라 프로젝트에 있는 Member 객체를 대상으로 한다. createQuery 메서드를 보면 JPQL이 작성되어 있다. 원래는 아스터리스크(*)로 표현되어야 할 첫 번째 m은 Member 엔티티의 값들을 불러온다. JPQL의 특징이다.

 

페이지네이션도 간단하다.

예) 5번 부터 8개 가져오기

페이지네이션에 출력되는 SQL은 SQL방언 설정에 따라 달라진다고 한다.

 

JPQL은 객체를 대상으로 하는 객체지향 SQL이라고 보면 된다.

 

 

 

JPQL 특징 정리

  • JPA를 사용하면 엔티티 객체를 중심으로 개발
  • 문제는 검색 쿼리
  • 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색
  • 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능
  • 애플리케이션이 필요한 데이터만 DB에서 불러오려면 결국 검색 조건이 포함된 SQL이 필요
  • JPA는 SQL을 추상화한 JPQL이라는 객체 지향 쿼리 언어를 제공
  • SQL과 문법 유사, SELECT, FROM, WHERE, GROUP BY, HAVING, JOIN 지원
  • JPQL은 엔티티 객체를 대상으로 쿼리
  • SQL은 데이터베이스 테이블을 대상으로 쿼리
  • 테이블이 아닌 객체를 대상으로 검색하는 객체 지향 쿼리
  • SQL을 추상화해서 특정 데이터베이스 SQL에 의존X
  • JPQL을 한마디로 정리하면 객체 지향 SQL

 


정리

데이터베이스

라이브러리 세팅 JPA, DB

persistenct.xml 세팅 필수

EntityManagerFactory 필수, 앱 전체에 하나 공유해서 사용한다. (설정 파일을 읽어서 만든다.)

EntityManager 생성 후 트랜잭션 안에서 쿼리를 만들어서 사용한다.

커밋 꼭 해야 한다.

사용한 자원은 꼭 닫아야 한다. (EntityManager, EntityManagerFactory)

WAS가 내려갈 때 EntityManagerFactory 닫아서, 커넥션 풀링이 내부적으로 릴리즈 되도록 한다.

 


좋아요, 구독, 광고 클릭은 큰 힘이 됩니다. :)

728x90
반응형