스터디를 통해 스프링부트와 AWS로 혼자 구현하는 웹 서비스(저자 이동욱) 서적을 공부하는 중입니다.
공부/실습한 내용을 정리한 포스팅입니다.
책에 모르는 부분이 있으면 구글링하거나 챗gpt에 물어봐서 보충하였습니다.
(아직 초보라 모르는 부분이 많아 이것저것 다 적었습니다.)
참고한 사이트 출처는 포스팅 맨 하단에 적었습니다.
domain
패키지 생성※ domain
: 게시글, 댓글, 회원, 정산, 결제 등 소프트웨어에 대한 요구사항 혹은 문제영역.
※ 기존의 MyBatis와 같은 SQL Mapper를 사용할 시 dao 패키지를 썼지만, domain 패키지와는 다름. xml에 쿼리를 담고, 클래스는 오로지 쿼리의 결과만 담지 않음.
domain
패키지에 posts
패키지 생성 후 Posts
클래스 생성Posts
클래스에 아래와 같이 작성package com.webservice.springboot.springboot_board.domain.posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import javax.persistence.*;
@Getter
@NoArgsConstructor
@Entity
public class Posts extends BaseTimeEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(length = 500, nullable = false)
private String title;
@Column(columnDefinition = "TEXT", nullable = false)
private String content;
private String author;
@Builder
public Posts(String title, String content, String author){
this.title=title;
this.content=content;
this.author=author;
}
public void update(String title,String content){
this.title = title;
this.content = content;
}
}
posts
패키지에 PostsRepository
인터페이스 생성PostsRespository
인터페이스에 아래의 코드 작성package com.webservice.springboot.springboot_board.domain.posts;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PostsRepository extends JpaRepository<Posts,Long> {
}
@NoArgsConstructor
※ Reflection API : 클래스의 정보를 얻고 다룰 수 있는 강력한 기능 제공
@Entity
@Id
@GeneratedValue
strategy
를 GenerationType.IDENTITY
로 둬야 auto_increment가 됨.웬만하면 Entity의 PK는 Long 타입의 Auto_increment 추천(MYSQL 기준 bigint). 주민등록번호와 같이 비즈니스상 유니크 키나 여러 키를 조합한 복합키로 PK로 잡을 경우 아래와 같은 상황 발생.
@Column
@Builder
※ 빌더 패턴 : 복잡한 객체의 생성 과정과 표현 방법을 분리하여 다양한 구성의 인스턴스를 만드는 생성 패턴. 생성자에 들어갈 매개 변수를 메서드로 하나하나 받아들이고 마지막에 통합 빌드해서 객체를 생성하는 방식.
※ 빌더 패턴의 장점
1. 점층적 생성자 패턴의 단점 해결
: 생성자 오버로딩 열거X
데이터 순서에 상관없이 객체를 만들어낼 수 있어 생성자 인자 순서를 파악할 필요X
2. Java Beans 패턴 문제 해결
: 일관성 문제(setter 메서드 미호출로 인한 객체가 유효하지 않는 문제), 불변성 문제(불변함을 보장하지 못하는 문제) 해결
※ 점층적 생성자 패턴 : 생성자 오버로딩 열거하는 방식.
※ Java Beans 패턴 : 매개변수가 없는 생성자로 객체 생성 후 Setter 메서드를 통해 클래스 필드의 초깃값 설정하는 방식.
domain.posts
패키지 생성 후 PostsRepositoryTest
클래스 생성package com.webservice.springboot.springboot_board.domain.posts;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.time.LocalDateTime;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
public class PostsRepositoryTest {
@Autowired
PostsRepository postsRepository;
@After
public void cleanup(){
postsRepository.deleteAll();
}
@Test
public void 게시글저장_불러오기(){
//given
String title = "테스트 게시글";
String content = "테스트 본문";
postsRepository.save(Posts.builder()
.title(title)
.content(content)
.author("jojoldu@gmail.com")
.build());
//when
List<Posts> postsList = postsRepository.findAll();
//then
Posts posts = postsList.get(0);
assertThat(posts.getTitle()).isEqualTo(title);
assertThat(posts.getContent()).isEqualTo(content);
}
@After
: JUnit에서 단위 테스트가 끝날 때마다 수행되는 메소드 지정. 보통 배포 전 전체 테스트 수행 시 테스트간 데이터 침범을 막기 위해 사용.save(Entity)
: 테이블에 insert, update 쿼리 실행.(id 있으면 update, 없으면 insert)findAll()
: 테이블에 있는 모든 데이터 반환.application.properties
.properties
: Java 응용프로그램 내 사용되는 설정을 적는 파일. 이 설정 파일을 외부에서 파일을 넣을 수도 있고, 프로젝트 내부적으로도 넣어서 사용할 수 있음.application.properties
파일 생성spring.jpa.show-sql=true
(H2는 MySQL 쿼리를 수행해도 정상적으로 작동)
application.properties
에 아래의 코드 추가spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
id bigint generated by default as identity
에서 id bigint not null auto_increment
로 변경됨메모리에서 실행하기 때문 직접 접근하기 위해선 웹 콘솔을 사용
1. application.properties
에 아래의 코드 추가 - 웹 콘솔 옵션 활성화
spring.h2.console.enabled=true
Entity Class에 Lombok @NoArgsConstructor(access=PROTECTED)를 붙이는 이유
💠 빌더(Builder) 패턴 - 완벽 마스터하기
springboot 개발 환경에 따른 properties 사용 방법 (local, dev, prod)
이번에는 Spring Data JPA를 적용하는 글을 읽었습니다. 글에서는 각 코드 라인이 어떤 역할을 하는지, 어떤 원리로 작동하는지에 대해 상세하게 설명하고 있어서 이해가 잘 됐습니다. Repository, Entity 클래스, 그리고 테스트 과정에 대한 부분이 특히 인상적이었습니다. 이런 유익한 글을 써주셔서 감사합니다. 앞으로도 좋은 글 기대할게요!