Showing

[스프링부트] 스프링부트에서 JPA로 데이터베이스 다루기 본문

JAVA, SPRING/스프링 부트와 AWS로 혼자 구현하는 웹서비스

[스프링부트] 스프링부트에서 JPA로 데이터베이스 다루기

RabbitCode 2023. 6. 1. 17:21

*이동욱 저, 스프링부트와 aws로 혼자 구현하는 웹서비스를 학습하면서 작성한 포스팅입니다.

 

1. SQL 보다 객체 지향 개발 : JPA

관계형 데이터베이스를 이용하는 프로젝트에서 객체지향 프로그래밍에 더욱 집중하기 위해 JPA라는 자바 표준 ORM 기술을 쓸 수 있다. 이번 챕터에서는 JPA를 프로젝트에 적용해보도록 한다. 많은 자사 서비스 기업이 SpringBoot & JPA를 전사 표준으로 사용하고 있다. 

 

2. 관계형 데이터베이스와 객체지향의 패러다임 불일치

현대의 웹 어플리케이션에서 관계형 데이터베이스(RDB, Relational Database)는 빠질 수 없는 요소. 객체를 관계형 데이터 베이스에서 관리하는 것이 무엇보다 중요하다.

관계형 데이터베이스가 계속해서 웹 서비스의 중심이 되면서 모든 코드는 SQL 중심이 되어갔다. 즉 현업 프로젝트 대부분이 애플리케이션 코드보다 SQL로 가득차게 된 것이다. 이는 관계형 데이터베이스가 SQL만 인식할 수 있기 때문인데, SQL로만 가능하니 각 테이블마다 기본적인 CRUD(Create, Read, Update, Delete) SQL을 매번 생성해야 한다. 예를 들어 User 객체를 테이블로 관리한다면 다음의 코드를 피할 수 없다.

insert into user (id, name, ...) values (...);
select * frmo user where ...;
update user set ... where ...;
delete from user where ...;

개발자가 아무리 자바 클래스를 아름답게 설계해도 SQL을 통해야만 데이터베이스에 저장하고 조회할 수 있다. 결국, 관계형 데이터베이스를 사용해야만 하는 상황에서 SQL은 피할 수 없다. 실제 현업에서 수십, 수백 개의 테이블이 있는데 이 테이블의 몇배의 SQL을 만들고 유지보수해야만 한다. 단순 박복 잡업을 수백번이상 해야하는 것이다. 

 관계형 데이터베이스는 어떻게 데이터를 저장할지에 초점이 맞춰진 기술이다. 반대로 객체지향 프로그래밍 언어는 메시지를 기반으로 기능과 속성을 한 곳에서 관리하는 기술이다. 관계형 데이터베이스로 객체지향을 표현하는 것이 쉽지 않은 것이다. 패러다임이 서로 다른데 객체를 데이터베이스에 저장하려고 하기 때문이다. 상속, 1:N 등 다양한 객체 모델링을 데이터베이스로 구현할 수 없다.

 

 3. JPA 소개

JPA는 위와 같은 문제점을 해결하기 위해 등장했다. 서로 지향하는 바가 다른 2개 영역(객체지향 프로그래밍 언어와 관계형 데이터베이스)을 중간에서 패러다임 일치를 시켜주기 위한 기술이다. 개발자는 객체지향적으로 프로그래밍을 하고, JPA가 이를 관계형 데이터베이스에 맞게 SQL을 대신 생성해서 실행한다. 개발자는 항상 객체지향적으로 코드를 표현할 수 있으니 더는 SQL에 종속적인 개발을 하지 않아도 된다. 객체 중심으로 개발을 하게 되니 생산성 향상은 물론 유지 보수하기가 정말 편하다. 이런 점 때문에 365일, 24시간, 대규모 트래픽과 데이터를 가진 서비스에서 JPA는 점점 표준 기술로 자리잡고 있다. 사실 JPA는 높은 러닝 커브를 자랑한다. JPA를 잘 쓰려면 객체지향 프로그래밍과 관계형 데이터베이스를 둘 다 이해해야 한다.

 하지만 JPA를 사용해서 얻는 보상은 크다. 가장 먼저 CRUD 쿼리를 직접 작성할 필요가 없다. 또한 부모-자식 관계 표현, 1:N 관계 표현, 상태와 행위를 한 곳에서 관리하는 등 객체지향 프로그래밍을 쉽게 할 수 있다.

 

 4. Spring Data JPA

JPA는 인터페이스로서 자바 표준명세서이다. 인터페이스인 JPA를 사용하기 위해서는 구현체가 필요하다. 다만 스프링에서 JPA를 사용할 떄는 이 구현체들을 직접 다루진 않는다. 구현체들을 좀 더 쉽게 사용하고자 추상화시킨 Spring Data JPA라는 모듈을 사용하여 JPA 기술을 다룬다. 이들의 관계를 보면 다음과 같다.

    JPA <- Hibernate <- Spring Data JPA

스프링 진영에서 Hibernate를 한단계 더 감싸놓은 Spring Data JPA가 등장한 이유는 두가지이다.

_1_ 구현체 교체의 용이성 : Hibernate 외에 다른 구현체로 쉽게 교체한다. Spring Data JPA 내부에서 구현체 매핑을 지원한다. 

_2_ 저장소 교체의 용이성 : 관계형 데이터베이스 외에 다른 저장소로 쉽게 교체하기 위함이다. 서비스 초기에는 관계형 데이터베이스로 모든 기능을 처리했지만, 점점 트래픽이 많아져 관계형 데이터베이스로는 도저히 감당이 안 될 때가 올 수 있다. 이때 MongoDB로 교체가 필요하다면 개발자는 Spring Data JPA에서 Spring Data MoongoDB로 의존성만 교체하면 된다. 이는 Spring Data의 하위 프로젝트들은 기본적인 CRUD의 인터페이스와 같기 때문이다. 즉 Spring Data JPA, Spring Data Redis, Spring Data MongoDB 등등 Spring Data의 하위 프로젝트들은 save(), findAll(), findOne() 등을 인터페이스로 갖고 있다. 그러다보니 저장소가 교체되어도 기본적인 기능은 변경할 것이 없다. 이런 장점들로 인해 Hibernate를 직접 쓰기 보다는 Spring 팀에서 계속해서 Spring Data 프로젝트를 권장하고 있다.

 

5. 요구사항 분석

앞으로 하나의 게시판(웹 어플리케이션)을 만들어 보고, AWS에 무중단 배포하는 것까지 진행하도록 한다. 이 게시판의 요구사항은 다음과 같다.

 

게시판 기능 회원 기능
 - 게시글 조회  - 구글/네이버 로그인
 - 게시글 등록  - 로그인한 사용자 글 작성 권한
 - 게시글 수정  - 본인 작성 글에 대한 권한 관리
 - 게시글 삭제  

 

어떤 웹 어플리케이션을 만들더라도 기반이 될 수 있게 보편적이지만 필수 기능들을 모두 구현하게 된다. 

요구사항 분석1

글 등록과 글 수정 역시 별도로 화면과 기능을 제공한다.