-
1. SpringBoot & JPA & TESTSpring-Boot/스프링부트와 AWS로 혼자 구현하는 웹 서비스 2022. 10. 26. 17:40
build.gradle
- ext : 전역변수 설정
- repositories : 각종 의존성( 라이브러리 )들을 어떤 원격저장소에 받을지를 정한다.
- dependencies : 프로젝트 개발에 필요한 의존성들 선언
@RestController - 컨트롤러를 JSON을 반환하는 컨트롤러로 만들어 준다.
- @ResponseBody 를 한번에 사용가능@GetMapping - HTTP Method인 GET요청을 받을 수 있는 API 생성 @RunWith(SpringRunner.class) - 테스트를 진행할 때 JUnit에 내장된 실행자 외에 다른 실행자를 실행시킨다.
- 여기서 SpringRunner라는 스프링 실행자를 사용
- 즉, 스프링 부트 테스트와 JUnit 사이에 연결자 역할을 한다.@WebMvcTest - 여러 스프링 테스트 어노테이션 중, Web(Spring MVC)에 집중할 수 있는 어노테이션이다.
- 선언할 경우 @Controller, @ControllerAdvice 등을 사용할 수 있다.
- 단, @Service, @Component, @Repository 등을 사용할 수 없다.@Autowired - 스프링이 관리하는 빈(Bean)을 주입 받는다. private MockMvc mvc - 웹 API를 테스트할 때 사용한다.
- 스프링 MVC 테스트의 시작점
- 이 클래스를 통해 HTTP GET, POST 등에 대한 API 테스트를 할 수 있다mvc.perform(get("/hello")) - MockMvc를 통해 /hello 주소로 HTTP GET 요청을 합니다
- 체이닝이 지원되어 아래와 같이 여러 검증 기능을 이어서 선언할 수 있다.andExpect(status().isOk()) - mvc.perform 의 결과를 검증한다.
- HTTP Header의 Status를 검증한다.
- 우리가 흔히 알고 있는 200,404, 500 등의 상태를 검증
- 여기서 OK, 즉 200인지 아닌지를 검증.andExpect(content().string(hello) - mvc.perform의 결과를 검증
- 응답 본문의 내용을 검증한다
- Controller에서 "hello"를 리턴하기 때문에 이 값이 맞는지 검증@Getter - 선언된 모든 필드의 get 메소드를 생성해준다 @RequiredArgsCOnstructor - 선언된 모든 final 필드가 포함된 생성자를 생성해 준다
- final이 없는 필드는 생성자에 포함되지 않습니다.assertThat - assertj라는 테스트 검증 라이브러리의 검증 메소드입니다
- 검증하고 싶은 대상을 메소드 인자로 받는다
- 메소드 체이닝이 지원되어 isEqualTo와 같이 메소드를 이어서 사용 가능isEqualTo - assertj의 동등 비교 메소드
- assertThat에 있는 값과 isEqualTo의 값을 비교해서 같을 때만 성공@Entity - 테이블과 링크될 클래스임을 나타냄
- 기본값으로 클래스의 카멜케이스 이름을 언더스코어 네이밍(_)으로 테이블 이름을 매칭한다
- ex) SalesManager.java → sales_manager table@Id - 해당 테이블의 PK 필드를 나타냄 @GeneratedValue - PK의 생성규칙을 나타낸다. @Column - 테이블의 컬럼을 나타내며 굳이 선언하지 않더라도 해당 클래스의 필드는 모두 컬럼이 된다
- 사용 이유는 기본값 외에 추가로 변경이 필요한 옵션이 있으면 사용
- 문자열의 경우 VARCHAR(255)가 기본값인데, 사이즈를 500으로 늘리고 싶거나, 타입을 TEXT로 변경하고 싶거나 등의 경우에 사용@NoArgsConstructor - 기본 생성자 자동 추가
- public Posts() {} 와 같은 효과@Getter - 클래스 내 모든 필드의 Getter 메소드 자동 생성 @Builder - 해당 클래스의 빌더 패턴 클래스를 생성
- 생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함* 웬만하면 Entity의 PK는 Long타입의 Auto_increment를 추천
ㆍ1. FK를 맺을 때 다른 테이블에서 복합키 전부를 갖고 있거나, 중간 테이블을 하나 더 둬야하는 상황 발생
ㆍ2. 인덱스의 좋은 영향을 끼치지 못합니다
ㆍ3. 유니크한 조건이 변경될 경우 PK 전체를 수정해야 하는 일이 발생
Spring 웹 계층
Web Layer
- 흔히 사용하는 컨트롤러(@Controller)와 JSP/Freemarker 등의 뷰 템플릿 영역입니다
- 이외에도 필터(@Filter), 인터셉터, 컨트롤러 어드바이스(@ControllerAdvice) 등 외부 요청과 응답에 대한 전반적인 영역
Service Layer
- @Service 에 사용되는 서비스 영역
- 일반적으로 Controller와 Dao의 중간 영역에서 사용
- @Transactional이 사용되어야 하는 영역
Repository Layer
- Database와 같이 데이터 저장소에 접근하는 영역
Dtos
- Dto(Data Transfer Object)는 계층 간에 데이터 교환을 위한 객체를 이야기하며 Dtos는 이들의 영역을 이야기한다
Domain Model
- 도메인이라 불리는 개발 대상을 모든 사람이 동일한 관점에서 이해할 수 있고 공유할 수 있도록 단순화시킨 것을 도메인 모델이라고 한다
- 이를테면 택시 앱이라고 하면 배차, 탑승, 요금 등이 모두 도메인이 될 수 있습니다
- @Entity 가 사용된 영역 역시 도메인 모델이라고 이해
- 다만, 무조건 데이터베이스의 테이블 관계가 있어야하는 것은 아니다.
* java8이 나오기 전까지 사용되었던 Date와 Calendar 클래스는 다음과 같은 문제점 존재 *
ㆍ1. 불변 객체가 아니다
ㆍ멀티스레드 환경에서 언제든 문제가 발생할 수 있다.
ㆍ2. Calendar는 월(Month) 값 설계가 잘못되었다.
→ LocalDate 나 LocalDateTime 사용할 것
BaseTimeEntity
@Getter @MappedSuperclass @EntityListners(AuditiongEntityListener.class) public abstract class BaseTimeEntity { @CreatedDate private LocalDateTime createdDate; @LastModifiedDate private LocalDateTime modifiedDate; }
@MappedSuperclass - JPA Entity 클래스들이 BaseTimeEntity 을 상속할 경우 필드들도 컬럼으로 인식 @EntityListeners(AuditingEntityListener.class) - BaseTimeEntity 클래스에 Auditing 기능을 포함 @CreatedDate - Entity가 생성되어 저장될 떄 시간이 자동 저장 @LastModifiedDate - 조회한 Entity의 값을 변경할 때 시간이 자동 저장 Querydsl 추천 이유
1. 타입 안정성 보장
- 단순한 문자열로 쿼리를 생성하는 것이 아니라, 메소드를 기반으로 쿼리를 생성하기 때문에 오타나 존재하지 않는 컬럼명을 명시할 경우 IDE에서 자동으로 검출한다.
2. 국내 많은 회사에서 사용 중이다.
3. 레퍼런스가 많다.
@Enumerated(EnumType.STRING) - JPA로 데이터베이스로 저장할 때 Enum 값을 어떤 형태로 저장할지 결정한다.
- 기본적으로 int로 된 숫자가 저장
- 숫자가 저장되면 데이터베이스로 확인할 때 그 값이 무슨 코드를 의미하는지 알 수가 없다.
-그래서 문자열 (EnumType.STRING)로 저장될 수 있도록 선언@Target(ElementType.PARAMETER) - 이 어노테이션이 생성될 수 있는 위치를 지정
- PARAMETER로 지정했으니 메소드의 파라미터로 선언된 객체에서만 사용
- 이외에도 클래스 선언문에 쓸 수 있는 TYPE 등이 있습니다@interface - 이 파일을 어노테이션 클래스로 지정