안녕! 안녕!
지난 챕터까지 해서 총 3번에 걸친 시간동안 JPA라는 녀석에 대해 이런 저런 이야기를 나눠보았는데..
이해가 충분히 됐을지 모르겠다.
사실 글을 올리는 필자도 아직까지 아리송한 부분이 많은데, 여러분 또한 다르지 않다고 생각한다.
그래서 JPA를 짤 한 장으로 요약하기 위해 저 사진을 가져왔다.
사진을 보면 구조가 한 눈에 보이지?
하나의 앱은 크게 세 파트로 요약이 된다는 것을 알 수 있다.
우리는 그 중에서도 서버와 DB 사이의 영역 (Spring Server ~ DB Server) 을 다뤄본 셈이다.
여기서 JPA는 어떤 기능을 수행하고 있겠는가?
한 눈에 보기에도 Repository와 DB 사이에서 SQL Query를 열심히 번역 (Interpreter) 을 하고 있다.
Java와 SQL은 서로 깊은 관계를 맺고 있지만 언어 체계는 완전히 다르다고 했다.
그렇다면 Repository는?
JPA 패키지를 클래스 하나에 전부 때려박은..
서플라이 디폿같은 녀석이라고 했다.
클래스 자체는 별도의 멤버변수를 두고 있지 않지만, 메소드만은 상속이 강제된다고 했지.
Repository를 상속하는 자식 클래스에서 SQL 기능을 좀 더 수월하게 구축하기 위해 만들었다.
// INSERT INTO TABLE (?,?,?,?,?) VALUES (?,?,?,?,?)
courseRepository.save();
// SELECT * FROM TABLE
courseRepository.findAll();
이런 식으로 가져다 쓴다는 것이다.
특히, SQL문을 읽을 수 있는 분들이라면 JPA가 새삼 얼마나 편리한 기능인지 실감이 갈 것이다.
필자는 여기에서 세미콜론만 빠지면 영락없는 파이썬 함수 같다고 비유한 적이 있다.
여기까지 훑어봤으면 브레인 스토밍이 충분히 됐을까?
뭔가 숨가쁘게 달려온 것 같지만 전체적인 맥락만 꿰고 있으면 어려울 거 하나도 없다.
이번 시간에는 저 JPA 함수를 좀 더 심화 학습해서 다뤄볼 것이다.
소스코드가 조금 더 복잡해졌을 뿐이다.
쫄지 말아라.
아! 그리고 여유가 된다면 Repository보다 앞 단인 Service 파트에 대해서도 이야기를 나눠보자.
글이 너무 늘어진다 싶으면 따로 포스팅을 올릴 것이다.
Okay, 렛츠기릿!

1. C.R.U.D
현업에서는 편리하게 크루드.. 라고 부르지.
웹 / 앱 백엔드 개발자라면 어떤 프로젝트를 수행하던지간에 CRUD로 시작해서, CRUD로 끝난다.
클라이언트와 서버간의 통신도 CRUD로 이루어지고..
서버와 DB간 통신 역시 CRUD가 빠질 수 없다.
그만큼 너무나도 중요한 내용이라는 것이다.
- CREATE (POST): 생성
- READ (GET): 조회
- UPDATE (PUT): 수정
- DELETE: 삭제
// INSERT INTO TABLE (?,?,?,?,?) VALUES (?,?,?,?,?)
courseRepository.save();
// SELECT * FROM TABLE
courseRepository.findAll();
이제 슬슬 눈에 익을 때도 되었을 것이다.
저번 시간에도 다뤄보았고, 이번 시간에도 이 녀석들을 가지고 놀아볼 것이다.
자! 퀴즈를 하나 내보겠다.
다음 소스코드에서 사용된 CRUD는 뭐가 있을까?
힌트를 주자면 두 가지 기능을 구현하였다.
...
...
...
...
...
...
충분히 생각해 보았는가?
당연히 스크롤만 내려봤겠지..
그냥 필자가 설명하겠다.
courseRepository.save(new Course("프론트엔드의 꽃, 리액트", "코드헨타이"));
뻔한 것 아니겠는가?
각각 두 개의 변수를 '저장' 하고 있다.
SQL문으로 풀어쓰면 다음과 같을 것이다.
INSERT INTO COURSE (TITLE, TUTOR) VALUES (?, ?);
둘을 비교해서 보면 이해가 좀 수월하겠는가?
여기까지 찾아서 들어올 정도의 여러분이라면 둘을 대조해서 봤을 때, 얼른 이해가 되어야 한다.
만약 그렇지 않다면 SQL 입문단계라도 선행학습 해오시길 바란다.
결론부터 말하자면 *.save Repository (이하 Repo) 에서는 데이터를 생성 (CREATE) 하고자 한다.
별도로 테이블을 만들어 줄 것도 없이 스프링에서 알아서 컬럼까지 밀어 넣어줄 것이다.
List<Course> courseList = courseRepository.findAll();
SELECT * FROM COURSE;
이 정도면 쉽지 모..
[findAll] 이 핵심이다.
'COURSE 테이블에 존재하는 모든 컬럼을 조회하시오!' 라는 명령을 JPA로 선언해 준 것 뿐이다.
그렇다면 여기서 구현된 CRUD는?
당연히 조회 (READ) 기능이겠지.
public interface CourseRepository extends JpaRepository<Course, Long> {...}
고작 이런 클래스를 하나 만들어 주었을 뿐이다.
Java 언어만 사용해서 아주 자유자재로 SQL문을 만들어주고 있지?
하지만 필자가 약을 팔고 있다고 생각하는 의심병 환자들도 분명히 있을 것이다.
그런 분들을 위한 증거가 여기에 있다.
Hibernate가 뭔지는 모르겠지만..
어디서 많이 본 적 있는 SQL 명령문이 콘솔창에 출력되고 있지?
정말 기똥찬 것이 여간 짜세가 아니다.
// 데이터 하나 조회하기
Course course = repository.findById(1L).orElseThrow(
() -> new IllegalArgumentException("해당 아이디가 존재하지 않습니다.")
);
짜잔~!
이렇게 데이터를 하나씩 조회하는 기능도 구현할 수 있다.
핵심은 역시 'findById()' 가 되겠지.
주저리 주저리 설명을 늘어뜨리는 것 보다는 SQL문과 대조해 보는 것이 이해가 빠를 것이다.
SELECT * FROM COURSE WHERE ID LIKE '1L';
이렇게 머리 속에서 두 가지 문법이 데칼코마니처럼 펼쳐져야 JPA를 제대로 쓸 수 있다.
만약 두 가지 개념이 무질서하게 뒤죽박죽 얽혀있는 분들은..
위에서도 강조했지만 반드시 SQL 문법을 선행학습 하고 오길 바란다.
JPA의 기능 자체를 암기하는 것이 아니라 SQL과 맞물려서 구조적으로 이해를 해야하는 것이다.
솔직히 JPA 하나만 하더라도 시중에서 책 한 권 분량으로 나올 정도로 내용이 방대하다.
그걸 다 외워서 쓸 수는 없잖아?
자!
글이 너무 늘어질 거 같으면 한 번 끊고, 두 번으로 나눠서 포스팅을 올린다고 했다.
그러니까 우선 여기서 마무리를 지어야 할 것 같다.
다음 시간에도 이어서 JPA를 심화학습 해보도록 하자.
이상!

'[JAVA] > JPA' 카테고리의 다른 글
5. JPA Advanced [Part.02] (0) | 2022.07.28 |
---|---|
3. Why JPA? (0) | 2022.07.25 |
2. JPA Basic (0) | 2022.07.23 |
1. JPA General (0) | 2022.07.21 |
0. Intro (0) | 2022.07.21 |