build.gradle에 다음과 같이 의존성들을 등록
compile('org.springframework.boot:spring-boot-starter-data-jpa') // 스프링 부트용 Spring Data JPA 추상화 라이브러리. 자동으로 JPA관련 라이브러리 버전을 관리
compile('com.h2database:h2') // 인메모리 관계형 데이터베이스. 별도의 설치가 필요없이 의존성만으로 관리 가능.
h2
: 메모리에서 실행되기 때문에 애플리케이션을 재시작할 때마다 초기화된다는 점을 이용하여 테스트 용도로 많이 사용된다
이 프로젝트에서는 JPA의 테스트, 로컬 환경에서의 구동에서 사용할 예정
domain 패키지 생성
: 도메인을 담을 패키지
-> 도메인 : 게시글, 댓글, 회원, 정산, 결제 등 소프트웨어에 대한 요구사항 혹은 문제 영역
(기존에 MyBatis와 같은 쿼리 매퍼를 사용할 때는 dao 패키지)
xml 에 쿼리를 담고, 클래스는 오로지 쿼리의 결과만 담던 일들이 이제는 도메인 클래스에서 일어남
Posts 클래스 생성
: Entity 클래스 (실제 DB의 테이블과 매칭될 클래스)
package com.jojoldu.book.springboot.domain.posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter // 클래스 내 모든 필드의 Getter 메소드를 자동생성
@NoArgsConstructor // 기본 생성자 자동 추가. public Posts(){} 와 같은 효과
@Entity // 테이블과 링크될 클래스임을 나타냄.
public class Posts {
@Id // 해당 테이블의 PK
@GeneratedValue(strategy = GenerationType.IDENTITY) // PK의 생성규칙. 스프링 부트 2.0 에서는 GenerationType.IDENTITY 옵션을 추가해야만 auto_increment가 됨
private Long id;
@Column(length = 500, nullable = false) // 굳이 선언하지 않아도 해당 클래스의 필드는 모두 컬럼이 된다. 기본값 외에 추가로 변경이 필요한 옵션이 있다면 사용.
private String title; // 문자열은 VARCHAR2(255)가 기본값인데 사이즈를 500으로 늘림
@Column(columnDefinition = "TEXT", nullable = false) // 타입을 TEXT로 변경
private String content;
private String author;
@Builder // 해당 클래스의 빌더 패턴 클래스를 생성. 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함
public Posts(String title, String content, String author) {
this.title = title;
this.content = content;
this.author = author;
}
}
보통 주요 어노테이션을 클래스 가까이 둔다
@Entity 는 JPA의 어노테이션
@Getter , @NoArgsConstructor는 롬복의 어노테이션 - 필수는 아님
-> 코틀린 등의 새 언어 전환으로 롬복이 더이상 필요없을 경우 쉽게 삭제 가능
* Entity 클래스에서는 절대 Setter 메소드를 만들지 않는다
: getter/setter를 무작정 생성하면 해당 크래스의 인스턴스 값들이 언제 어디서 변해야하는지 코드상으로 명확하게 구분할 수가 없어,
차후 기능 변경 시 복잡해진다.
대신, 해당 필드의 값 변경이 필요하면 명확히 그 목적과 의도를 나타낼 수 있는 메소드를 추가해야만 한다.
주문 취소 메소드 잘못된 예시
public class Order{
public void setStatus(boolean status){
this.status = status
}
}
public void 주문서비스의_취소이벤트(){
order.setStatus(false);
}
올바른 예시
public class Order{
public void cancelOrder(){
this.status = false;
}
}
public void 주문서비스의_취소이벤트(){
order.cancelOrder();
}
* Setter가 없는 이 상황에서 어떻게 값을 채워 DB에 삽입하는가?
생성자를 통해 최종값을 채운 후 DB에 삽입
+ 값 변경이 필요한 경우 : 해당 이벤트에 맞는 public 메소드를 호출
이 프로젝트에서는 생성자 대신 @Builder를 통해 제공되는 빌더 클래스를 사용
생성자, 빌더 : 생성 시점에 값을 채워주는 역할
but 생성자는 지금 채워야 할 필드를 명확히 지정할 수 없음
ex) 생성자
public Example(String a, String b){
this.a = a;
this.b = b;
}
개발자가 new Example(b,a) 처럼 a와 b의 위치를 변경해도 코드를 실행하기 전까지는 문제를 찾을 수가 없다
ex) 빌더
Example.builder()
.a(a)
.b(b)
.build();
어느 필드에 어떤 값을 채워야 할지 명확하게 인지 가능하다.
PostsRepository 생성
: Posts 클래스로 DB를 접근하게 해 주는 JPARepository
package com.jojoldu.book.springboot.domain.posts;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostsRepository extends JpaRepository<Posts, Long> {
}
보통 MyBatis 등에서 Dao
JPA에서는 Repository
: 인터페이스로 생성 후
JpaRepository<Entity 클래스, PK타입>을 상속하면 기본적인 CRUD 메소드 자동 생성
@Repository 추가할 필요 없음
* 주의 : Entity 클래스와 기본 Entity Repository는 함께 위치해야함 - 도메인 패키지에서 함께 관리
Entity 클래스는 기본 Repository 없이는 제대로 역할을 할 수 없다
'기록 > 스프링 부트와 AWS로 혼자 구현하는 웹 서비스' 카테고리의 다른 글
Chapter 3. Spring Data JPA 테스트 코드 작성하기 (0) | 2022.10.11 |
---|---|
Chapter 3. 스프링 부트에서 JPA로 데이터베이스 다뤄보기 (0) | 2022.10.07 |
Chapter 2. Hello Controller 코드를 롬복으로 전환하기 (0) | 2022.10.04 |
Chapter 2. 스프링 부트에서 테스트 코드 작성 (0) | 2022.09.29 |
Chapter 2 - 롬복 소개 및 설치하기 (0) | 2022.09.24 |