스프링 부트와 AWS로 혼자 구현하는 웹 서비스
https://github.com/HYEBPARK/springboot-webservice
3장. 스프링 부트에서 JPA로 데이터베이스 다루기
3.1 JPA 소개
📍 관계형 DB를 이용하는 project에서 OOP 문제점
- 관계형 데이터베이스는 SQL만 인식 -> 단순 반복 작업 문제
- 패러다임 불일치
-> RDB는 어떻게 데이터를 저장할지에 초점
-> OOP는 메시지를 기반으로 기능과 속성을 한 곳에서 관리하는 기술
=> 위의 문제 해결 = ORM
📍 ORM(Object Relational Mapping)
: 객체와 관계형 데이터 베이스를 자동으로 매핑해준다.
- 개발자는 객체지향적으로 코드 표현 가능 -> 직관적
- SQL에 종속적인 개발을 하지 않아도 된다.
- 유지보수가 편하다.
📍 JPA(Java Persistence API)
: 자바 표준 ORM, 자바 어플리케이션에서 RDB를 사용하는 방식을 정의한 인터페이스
=> 사용을 위해서는 구현체가 필요하다. EX) Hibernate, Eclipse Link, DataNucleus 로 인터페이스를 직접 구현한 라이브러리이다.
📍 요구사항 분석
- 게시판
- 게시글 조회
- 게시글 등록
- 게시글 수정
- 게시글 삭제
- 회원
- 구글 / 네이버 로그인
- 로그인한 사용자글 작성 권한
- 본인 작성 글에 대한 권한 관리
3.2 프로젝트에 Spring Data Jpa 적용하기
📍 의존성 등록
- spring-boot-starter-data-jpa : Springboot용 Spring Data Jpa 추상화 라이브러리
=> Springboot 버전에 맞춰 자동으로 JPA관련 라이브러리 버전 관리
- h2 : 인메모리 관계형 데이터베이스, 설치 필요 없이 의존성만으로 관리 가능
=> 메모리에서 실행되기 때문에 애플리케이션을 재시작할 때마다 초기화, 테스트 용도로 많이 사용
📍 도메인 패키지
-
domain? 게시글,댓글,회원,정산,결제 등 소프트웨어에 대한 요구사항 혹은 문제영역
-
JPA
- @Entity : 테이블과 링크될 클래스임을 나타낸다.
- @Id : 해당 테이블의 PK필드를 나타낸다.
- @GeneratedValue : PK의 생성 규칙 , GenerationType.IDENTITY 옵션 추가 => auto_increment 가능
- @Column : 테이블의 칼럼을 나타내며, 기본값 외에 추가로 변경이 필요한 옵션이 있으면 사용 => 필수 x
-
lombok
- @NoArgsConstructor : 기본생성자 자동추가
- @Getter : 클래스 내 모든 필드의 Getter 메소드를 자동생성
- @Builder : 해당 클래스의 빌더 패턴 클래스 생성
# 빌더패턴 : 복잡한 객체의 생성 과정과 표현 방법을 분리하여 동일산 생성 절차에서 서로 다른 표현 결과를 만들 수 있게 하는 패턴
-
실제 실행된 쿼리를 로그로 확인하기
// application.properties 에 추가
spring.jpa.show_sql = true
3.4 등록/수정/조회 API 만들기
- Request 데이터를 받을 Dto
- API요청을 받을 Controller
- 트랜잭션, 도메인 기능 간의 순서를 보장하는 Service
📍 Spring web 계층
- Web Layer
- 흔히 사용하는 @Controller와 JSP/Freemarker 등의 뷰 템플릿 영역
- @Filter, 인터셉터, @ControllerAdvice 등 외부 요청과 응답에 대한 전반적인 영역
- Service Layer
- @Service에 사용되는 서비스 영역, Controller와 Dao의 중간영역에서 사용
- @Transaction이 사용되어야 하는 영역
- Repository Layer
- Database와 같이 데이터 저장소에 접근하는 영역
- Dtos
- Dto(Data Transfer Object)는 계층 간에 데이터 교환을 위한 객체이며 Dtos는 이들의 영역
- ex) 뷰 템플릿 엔진에서 사용될 객체, Repository Layer에서 결과로 넘겨준 객체 등
- Domain Model
- 도메인이라 불리는 개발 대상을 모든 사람이 동일한 관점에서 이해하고 공유할 수 있도록 단순화
- ex) 택시 앱의 배차, 탑승, 요금 등이 모두 도메인이 될 수 있다.
- @Entity가 사용된 영역 또한 도메인 모델
- 비지니스 처리를 담당
📍 spring에서 Bean을 주입받는 방식
- @Autowired
- setter
- 생성자 ✔ 사용
=> @RequiredArgsConstructor : final이 선언된 모든 필드를 인자값으로하는 생성자를 생성
📍 update기능에서 database에 쿼리를 날리는 부분이 없는 이유
=> JPA의 Persistence context : entity를 영구 저장하는 환경
- 영속성 컨텍스트가 유지된 상태 : JPA의 EntityManager가 활성화된 상태로 트랜잭션 안에서 데이터베이스에서 데이터를 가져온다.
- 영속성 컨텍스트가 유지된 상태에서 해당 데이터의 값을 변경하면 트랜잭션이 끝나는 시점에 해당 테이블에 변경분을 반영, 별도로 Update 쿼리를 날릴 필요가 없다. => dirty checking
🥔 PostsApiControllerTest 코드 오류
🤷♀️ 다른분들의 이슈를 다 참고하여 고쳐보고 그래들 버전 업그레이드도 해봤지만 계속해서 JSON 파싱 오류가 난다. 더 이상 방법을 모르겠어서 이슈를 올렸다.
🤦♀️ 8/8 해결 : PostApiConroller에 update 코드를 추가하지 않았다...
💡 참조