제이제이
article thumbnail

 

1. JPA란 Java Persistance API 입니다.


❓ Persistance(영속성)이란?

🔥 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성을 의미합니다.
  • 영속성은 파일 시스템, RDBMS 또는 객체 데이터베이스 등을 활용하여 구현합니다.

이를 이해하기 전 먼저 다음의 예를 먼저 살펴봅시다.

컴퓨터에서의 데이터를 읽고 접근할 수 있는 방법에는 휘발성인 RAM 비 휘발성인 하드 디스크가 있는데 각각의 특징은 다음 그림과 같습니다.

 

보통 자바 프로그램은 하드디스크에서 DBMS를 이용해 데이터를 기록하고 관리합니다.

 

❓DBMS란?

  • 데이터베이스 관리 시스템을 의미합니다.

❓JPA란 결국 무엇을 의미하는 것일까?

🔥 자바에 있는 데이터를 영구히 기록할 수 있는 환경(ex. 하드디스크의 DBMS)을 제공하는 API입니다.

 

그럼 다음으로 API에 대해서 알아보겠습니다.

❗ API란?

🔥 애플리케이션(A) 프로그래밍(P) 인터페이스(I)를 의미합니다.

 

 

다음으로 인터페이스에 대해서 알아봅시다.

 

❓ 인터페이스란 뭐야?

인터페이스를 이해하기 위해 프로토콜과 함께 비교하여 알아봅시다.

💡 프로토콜 VS 인터페이스의 비교(차이점)

 

프로토콜

🔥 서로 동등한 관계에서의 약속, 규칙을 의미합니다.

 

인터페이스

🔥 상-하 관계가 존재하는 관계에서의 약속, 규칙을 의미합니다.

 

프로토콜과 인터페이스의 비교를 한눈에 보기

정리

🔎 JPA(Java Persistance API)란?

🔥 Java 프로그래밍을 할 때 영구적으로 데이터를 저장하기 위해 필요한 인터페이스입니다.

2. JPA란 ORM입니다.


❓ ORM이란?

🔥 Object Relational Mapping의 약자로써 객체간의 관계를 매핑(연결)하는 것을 의미합니다.

 

먼저 모델링의 개념을 알고 넘어갑시다.

 

❓ 모델링이란?

🔥 추상적인 개념을 현실세계의 개념으로 뽑아내는 것을 의미합니다.
  • 위의 그림처럼 설계도를 바탕으로 건축 모형을 만드는 것을 “모델링한다”라고 합니다.

 

다음과 같이 DB의 테이블 자바 프로그램이 있다고 가정하겠습니다.

 

 

프로그래밍의 순서

🔥 먼저 1.DB 속 Team의 테이블을 만든 후 2.자바 프로그램에에서 이를 이용하도록 프로그래밍하게 됩니다.

 

❗ 문제점

자바 프로그램의 데이터 타입과 DB에 있는 자료형 타입이 서로 다르다는 문제가 있습니다.

우리는 위와 같은 방식을 “DB에 있는 데이터를 자바 프로그램에 모델링한다!”라고 합니다.

반면 ORM에는 위의 프로그램 작성 순서가 다음과 같이 변경됩니다.

 

 

ORM 프로그래밍의 순서

🔥 1. 자바 프로그램에서 DB에 저장하고 싶은 데이터를 생성한 후 실행 하면 2. DB 속에 Team 테이블이 생성됩니다.

 

ORM을 통해 자바 클래스의 데이터를 DB에 Mapping하게 됩니다.

즉, 테이블을 통한 매핑(TRM:Table Relational Mapping)이 아닌 ORM을 통해 매핑하게 됩니다.

이 때 필요한 것이 JPA의 인터페이스 입니다.

정리

ORM(Object Relational Mapping)이란?

🔥 객체간의 관계를 매핑(연결)하는 것을 의미하며,
     JPA의 인터페이스 규칙을 지키면서 클래스를 만들어 데이터베이스에 자동으로 생성하는 기법입니다.

3. JPA란 반복적인 CRUD 작업을 생략하게 해줍니다.


❓CRUD란?

🔥 생성(Create),조회(Read), 수정(Update), 삭제(Delete)를 의미합니다.

 

다음 그림을 통해 CRUD의 작업을 이해하고 넘어갑시다.

 

 

CRUD 작업은 굉장히 자주 반복되어 일어납니다.

다음으로 CRUD가 일어나는 과정을 살펴보겠습니다.

 

CRUD가 일어나는 과정

 

과정

첫번째 요청

1. 자바 프로그램은 DB에 첫번째 요청을 통해 Connection을 요청합니다.

2. DB는 확인을 하고 세션을 오픈합니다.(세션 오픈)

→ 자바 프로그램과 연결이 됩니다.

3. 자바 프로그램이 Connection을 가집니다.

 

두번째 요청

4. 첫번째 요청으로부터 Connection이 연결된다면 두번째 요청부터는 DB에 쿼리를 전송할 수 있습니다.

5. DB는 테이블을 생성합니다.

6. DB에서 테이블을 생성한 후 자바 프로그램에게 응답을 줍니다.

7. 자바 프로그램은 DB의 응답을 받고 DB의 데이터 타입과 자바 프로그램상의 데이터 타입이 다르기 때문에
자바는 해당 데이터를 받아 자바 Object로 변경합니다.

 

이 과정은 엄청난 로직이 아닌 단순한 반복 로직입니다.

 

JPA는 이러한 반복 로직을 줄이게 합니다. (JPA에서는 함수 하나로 위와 같은 반복 로직을 할 수 있게 제공합니다.)

정리

JPA는 CRUD를 단순하게 처리하도록 도와줍니다. 또한 내가 만든 클래스를 자동으로 테이블로 생성해주기 때문에 단순한 반복로직을 ORM으로 처리합니다.

4. JPA는 영속성 컨텍스트를 가지고 있습니다.


이전에 “영속성”에 대한 의미를 알아봤었습니다.

💡 영속성이란?

🔥 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성을 의미합니다.

 

❓ 그럼 컨텍스트란?

🔥 “대상에 대한 모든 정보”를 영구히 저장하는 환경을 의미합니다.

 

❗ ”컨텍스트를 넘겨준다”라는 의미

🔥 대상에 대한 모든 정보를 넘겨줌으로써 해당 대상의 모든 정보를 알게됨을 의미합니다.

1) 데이터를 생성했을 때, 삭제했을 때(Create, Delete)

다음의 그림을 살펴봅시다.

 

과정

그림처럼 자바 프로그램에 동물 데이터가 있다고 가정하겠습니다.

1. 자바 프로그램에서 영속성 컨텍스트에게 동물 데이터를 전달합니다.

2. 영속성 컨텍스트 DB 동물 데이터를 전달함으로 최종적으로 DB에 동물에 대한 정보가 생기게 됩니다.

3. 만약 자바 프로그램에서 동물 데이터를 삭제하게 되었습니다.

4. 영속성 컨텍스트 동물 데이터를 삭제합니다.

5. DB에서도 동물 데이터를 삭제합니다.

위의 과정을 통해 영속성 컨텍스트는 DB와 동기화 됨을 알 수 있습니다.

2) 데이터를 조회할 때(Read)

다음의 그림을 살펴봅시다.

 

과정

그림처럼 DB에 있는 과일 데이터가 있을 때 자바 프로그램에서 조회할 경우를 가정하겠습니다.

1. 자바 프로그램에서 영속성 컨텍스트에게 과일 데이터를 조회를 요청합니다.(Select 요청)

2. 영속성 컨텍스트 DB에게 과일 데이터를 전달해달라고 요청합니다.

3. 영속성 컨텍스트 과일 데이터를 딸기 데이터로 변경합니다.

4. DB에서는과일 데이터를 응답합니다.

5. 영속성 컨텍스트 과일 데이터 자바 Object로 변경하여 자바 프로그램에게 넘겨줍니다.

3)데이터를 변경했을 때(Update)

다음의 그림을 살펴봅시다.

 

과정

그림처럼 자바 프로그램에 과일 데이터가 있다고 가정하겠습니다.

1. 자바 프로그램에서 영속성 컨텍스트에게 과일 데이터를 전달합니다.

2. 영속성 컨텍스트 DB 과일 데이터를 전달함으로 최종적으로 DB에 과일에 대한 정보가 생기게 됩니다.
(자바프로그램 - 영속성 컨텍스트 - DB에 있는 과일 데이터는 내용이 일치하게 됩니다.)

3. 그 다음 만약 자바 프로그램에서 과일 데이터 딸기 데이터로 변경하게 되었습니다.

4. 영속성 컨텍스트 과일 데이터 딸기 데이터로 변경합니다.

5. 이를 DB에서도 과일 데이터 딸기 데이터로 변경합니다.
(변경 과정 중 Insert가 아닌 Update가 일어나게 됩니다.)

정리

❓영속성 컨텍스트란?

🔥 자바 프로그램의 정보를 DB에 저장하고, 필요한 DB의 데이터를 선택하여 자바 프로그램에 가져오는 모든 정보를 수행합니다.
  • 자바 프로그램이 DB에 저장해야 하는 모든 메타 데이터들을 영속성 컨텍스트가 가지고 있습니다.
  • 영속성 컨텍스트에서 일어나는 일들은 모두 자동으로 일어납니다.

5. JPA는 DB와 OOP의 불 일치성을 해결하기 위한 방법론을 제공합니다.


다음 그림을 살펴봅시다.

Player테이블의 TeamID Team테이블의 ID 외래키(FK)로 설정했음을 알 수 있습니다.

즉, Team테이블의 ID를 참조합니다.

 

❗주목해야 할 점

DB가 가질수 있는 데이터의 유형

🔥 DB는 기본 자료형만 가질 수 있습니다. (즉, Object를 가질 수 없습니다.)

 

위의 DB 데이터를 모델링하면 하면 다음과 같습니다.

Team 테이블을 모델링한 예(Team 클래스)

class Team{
    int id;
    String name;
    String year;
}

 

Player 테이블을 모델링한 예(Player 클래스)

class Player{
    int id;
    String name;
    int teamId;

}

 

분석

Player 클래스는 teamId를 int형으로 가지고 있습니다.

 

❓만약 Player DB 테이블에서 가득염을 조회(Select)한다면?

Player 클래스에 id = 2, name = 가득염, teamId =1 로 들어가게 됩니다.

 이렇게 되면 가득염이 어느 팀에 속해 있는지 모르게 됩니다.

(프로그래머는 알지만 웹 페이지를 보는 클라이언트는 모릅니다.)

 

따라서 어떤 팀인지 보여주려고 한다면 다음과 같은 작업이 추가로 필요합니다.

1. teamId = 1로 DB 테이블에서 어떤 팀인지 찾아와야 합니다.
(어떤 팀인지 select문을 하거나)

2. 테이블 조인을 통해서 해결해야 합니다.

 

❗ 그런데 자바 프로그램에서는 Object를 사용할 수 있습니다.

따라서 위의 코드의 Player에서 Object인 team을 사용할 수 있습니다.

 

Team 테이블을 모델링한 예(Team 클래스)

class Team{
    int id;
    String name;
    String year;
}

 

Player 테이블을 모델링한 예(Player 클래스)

class Player{
    int id;
    String name;
    Team teamId;

}

🚨 문제

🔥 DB에 저장되어 있는 Player 테이블과 불일치하게 됩니다.
  • DB의 Player 테이블의 teamId는 Int형이기 때문입니다.

🔎 해결 방법

🔥 이때 ORM을 이용하면 모델을 만들 때 자바가 주도권을 쥐고 있는 모델을 만들 수 있습니다.
  •  Team team; 으로 선언이 가능하게 됩니다.

💡 ORM을 하게 된다면?

🔥 자바 프로그램에서 저장할 때는 객체를 통해 저장하며
      JPA가 DB에 있는 데이터를 조회, 삽입할 때는 자동으로 Foreign Key를 넣어줍니다.

6. JPA는 OOP의 관점에서 모델링을 할 수 있게 합니다.(상속, 컴포지션, 연관관계)


다음과 같이 자바코드로 자동차를 의미하는 Car클래스 엔진을 의미하는 Engine 클래스가 있습니다.

Car 클래스(자동차를 의미)

class Car{
 int id;
 String name;
 String color;

}

 

Engine 클래스(엔진을 의미)

class Engine{
 int id;
 int power;
}

 

❓Car클래스에서 Engine을 나타내고 싶다면?

🔥 상속이 아닌 결합(콤포지선)을 이용해 나타내야합니다.

 

❓왜 Car클래스에서 Engine을 상속하면 안되는가?

🚨 만약 상속을 하게 되면 Engine클래스가 부모 클래스가 되고 Car 클래스는 자식 클래스가 됩니다.
      즉, 자동차의 부모가 엔진이 되기 때문에 상속을 통해서는 처리하면 안됩니다.

OOP관점에서의 모델링을 한 결과

위의 Car 클래스와 Engine 클래스를 OOP관점에서 다음과 같이 만들 수 있습니다.

 

Car 클래스(자동차를 의미)

class Car{
 int id;
 String name;
 String color;
 Engine engine;
}

 

Engine 클래스(엔진을 의미)

class Engine{
 int id;
 int power;
}

 

JPA는 클래스를 먼저 만들고 해당 클래스를 대상으로 자동으로 DB 테이블을 만들어 준다고 이전에 알아봤었습니다.

그 다음으로 JPA를 통해 위의 두 클래스가 DB에서 어떻게 생기는지 알아봅시다.

DB에서 생성될 Car,Engine 클래스

JPA를 통해 위의 Car클래스와 Engine 클래스는 다음과 같이 생성됩니다.

정리

위의 내용을 정리하면 다음과 같습니다.

그 다음으로 위에서 보지 못했던 상속에 대해서도 살펴봅시다.

상속

만약 위의 Car 클래스 Engine 클래스 만든 날짜와 업데이트된 날짜를 넣고 싶으면 어떻게 할까요?

먼저 만든 날짜와 업데이트를 날짜를 표시하는 EngineDate클래스를 새로 생성합니다.

 

EntityDate클래스(만든 날짜와 업데이트 날짜를 표기)

class EntityDate{
    TimeStamp createDate;
    TimeStamp updateDate;
}

 

그 다음 Car클래스 Engine클래스에 EntityDate클래스를 상속하면 됩니다.

Car 클래스(자동차를 의미)

class Car extends EntityDate{
 int id;
 String name;
 String color;
 Engine engine;
}

 

Engine 클래스(엔진을 의미)

class Engine extends EntityDate{
 int id;
 int power;
}

 

그럼 DB에서는 다음과 같이 Car클래스 Engine 클래스에 Entity Date의 필드가 추가되어 생성됩니다.

7. 방언처리가 용이하여 Migration과 유지보수를 하기에 좋습니다.


스프링은 JPA를 통해 DB에 접근하는 방법에 대해서 알아봤습니다.

사실 데이터베이스를 관리하는 시스템(DBMS)들은 여러개가 있습니다.

 

❓그런데 JPA가 MySQL만 지원한다면??

🚨 MySQL를 통해서만 DB에 접근이 가능하다는 문제점이 있습니다.

 

또한 각 DBMS들마다 표준 SQL외에 사용하는 서로 다른 SQL문들이 존재합니다.

 

각 DBMS들은 표준 SQL외에 제공하는 SQL구문들??

🚨 SQL은 모든 DBMS에서 사용가능한 표준 ANCI SQL이 있고 각 DBMS마다 제공하는 SQL문들이 존재합니다.

 

  • 대표적으로 Oracle DBMS에서 사용하는 PL/SQL이 있습니다.
  • 각기 다른 DBM에서 만든 SQL문은 자신들만의 독자적인 기능을 추가하기 위해 만든 것이므로
    사용하는 해당 DBMS에서만 사용이 가능합니다.

따라서 Oracle의 DBMS에서 Mysql의 DBMS로 변경할 때
Oracle사에서 사용하던 SQL문이라도 Mysql로 변경할 때 수많은 SQL문들을 변경해야 합니다.

이러한 각 DBMS마다 별도로 사용하는 SQL문 들을 우리는 방언(dialect)라고 합니다.

 

❓방언이란?

🔥 각 DBMS마다 표준 ANSI SQL외에 별도로 사용하는 SQL문을 의미합니다.

JPA의 방언(dialect)처리

 

❓JPA는 어떻게 방언을 처리할까?

🔥 JPA에서는 방언(dialect)를 설정할 수 있는 추상화 객체(추상화 방언 클래스)를 제공하고
      설정된 방언으로 각 DBMS에 맞는 구현체를 제공합니다.

ex)

Oracle DB를 사용하다가 MySQL을 사용하고 싶다면 방언(dialect)를 Mysql로 설정하면 됩니다.
즉, DBMS의 종류에 상관없이 자신이 사용하고 싶은 DBMS를 변경하여 사용할 수 있습니다.

이를 그림으로 살펴보면 다음과 같습니다.

8. JPA는 쉽지만 어렵다.


JPA는 RDBMS와 달라 처음에 접할 때는 어렵지만 익숙해질수록 쉽습니다.

 

📒 Reference(참고자료)


 

[무료] 스프링부트 개념정리(이론) - 인프런 | 강의

스프링부트를 공부하며 헷갈리는 개념이 많았던 분 스프링부트에 대해 공부하고 싶었던 모든 분, - 강의 소개 | 인프런...

www.inflearn.com

profile

제이제이

@아사비치즈스틱

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!