Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plan/3. study_plan-curriculum.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@

### 📅 3주차
- **3.1.** JPA 심화 학습
- **3.1.1.** Converter 사용
- **3.1.1.** AttributeConverter 사용
- **3.1.2.** Embeddable 사용
- **3.1.3.** Auditing 사용
- **3.1.4.** ManyToOne, OneToMany 사용
- **3.2.** Spring Boot 테스트 코드 작성
- **3.2.1.** 단위 테스트 (Unit Test) 작성
- MockMvc 사용
- **3.2.2.** 통합 테스트 (Integration Test) 작성
- **3.2.3.** MockMvc 사용
- **3.3.** RESTful API 설계 및 구현
- **3.3.1.** RESTful API 기본 원칙
- **3.3.2.** Request, Response DTO 클래스 작성
Expand Down
75 changes: 69 additions & 6 deletions plan/4.3. study_plan-week-3-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,85 @@
## 📜 스터디 요약
### 📅 3주차
- **3.1.** JPA 심화 학습
- **3.1.1.** Converter 사용
- **3.1.2.** Embeddable 사용
- **3.1.3.** Auditing 사용
- **3.1.4.** ManyToOne, OneToMany 사용
- **3.1.1.** `AttributeConverter` 사용
- `AttributeConverter`란 DB 컬럼과 엔티티 필드 간의 변환을 담당하는 인터페이스
- `@RequestParam`, `@PathVariable` 등으로 전달되는 값의 타입을 변환할 때 사용하는 `Converter`와는 다름
- **3.1.2.** `Embeddable` 사용
- `Embeddable`은 `VO`(Value Object)를 표현하는데 사용되며, 재사용 가능한 `VO`를 쉽게 활용할 수 있도록 도와줌
- DB 테이블에 `VO`의 필드가 그대로 매핑되는 것이 아니라, `VO`의 필드가 엔티티의 필드로 포함되어 매핑됨
- e.g. `Address` 클래스를 `User` 엔티티에 포함시키기
- ```mysql
CREATE TABLE user (
id BIGINT PRIMARY KEY,
name VARCHAR(255),
city VARCHAR(255),
street VARCHAR(255),
zipcode VARCHAR(255)
);
```
- ```java
@Embeddable
public class Address {
private String city;
private String street;
private String zipcode;
}
```
- ```java
@Entity
public class User {
@Id
@GeneratedValue
private Long id;

private String name;

@Embedded
private Address address;
}
```
- OOP(Object Oriented Design)의 목적인 **캡슐화**를 지원함
- OOP의 캡슐화: 객체의 상태(필드)와 행위(메서드)를 하나로 묶고, 외부에서 객체의 상태를 직접 변경하지 않도록 함
- `Address` 클래스의 필드를 `User` 엔티티의 필드로 포함시킴으로써, `Address` 클래스의 내부 구현을 외부로부터 숨길 수 있음
- `Address` 클래스의 필드에 대한 관련 로직(검증 등)이 추가되어도, `User` 엔티티의 코드를 수정하지 않아도 됨
- `@Embeddable`과 `@Embedded` 어노테이션을 사용하여 엔티티에 `VO`를 포함시킬 수 있음
- **3.1.3.** `Auditing` 사용
- **3.1.4.** `ManyToOne`, `OneToMany` 사용
- **3.2.** Spring Boot 테스트 코드 작성
- **3.2.1.** 단위 테스트 (Unit Test) 작성
- MockMvc 사용
- `MockMvc`는 Spring MVC 테스트를 위한 클래스로, 서버를 띄우지 않고도 컨트롤러 테스트를 수행할 수 있음
- 테스트 관점에서의 Request, Response DTO 클래스 작성의 필요성
- 계층 별로 DTO 클래스를 작성하지 않을 시, 의존성이 높아지고 테스트 작성이 어려워짐
- Entity 클래스를 Request, Response DTO로 사용할 경우, JPA 의존성을 테스트 시 포함시켜야 하므로 테스트가 어려워짐
- **3.2.2.** 통합 테스트 (Integration Test) 작성
- `@SpringBootTest` 어노테이션을 사용하여 스프링 컨테이너를 띄우고 테스트를 수행
- `@Transactional` 어노테이션을 사용하여 테스트가 종료될 때 롤백 처리
- **3.3.** RESTful API 설계 및 구현
- **3.3.1.** RESTful API 기본 원칙
- RESTful API는 **자원(URI)**을 표현하고, **행위(HTTP Method)**를 통해 자원을 처리함
- `GET /api/users`: 사용자 목록 조회
- `GET /api/users/{id}`: 사용자 조회
- `GET /api/users/{id}/address`: 사용자의 주소 목록 조회
- `POST /api/users`: 사용자 생성
- `POST /api/users/{id}/address`: 사용자의 주소 생성
- `PUT /api/users/{id}`: 사용자 정보 수정
- `PUT /api/users/{id}/address/{addressId}`: 사용자의 주소 정보 수정
- `PUT /api/users/{id}/password`: 사용자의 비밀번호 수정
- `PUT /api/users/{id}/password-reset`: 사용자의 비밀번호 초기화
- `DELETE /api/users/{id}`: 사용자 삭제
- 데이터 전송 관점에서의 Request, Response DTO 클래스 작성의 필요성
- 필드 추가, 삭제 등의 변경이 있을 때, API 스펙이 변경되지 않도록 함
- Entity 클래스의 필드와 API 스펙이 일치하지 않도록 함
- **3.3.3.** API 예외 처리
- **3.3.4.** Spring Validation 사용
- **3.3.5.** Converter 사용
- **3.3.6.** Serializer/Deserializer 사용
- **3.3.5.** `Converter` 사용
- `Converter`는 `@RequestParam`, `@PathVariable` 등으로 전달되는 값의 타입을 변환할 때 사용
- **3.3.6.** `Serializer`/`Deserializer` 사용
- `Serializer`는 객체를 JSON 형태로 변환할 때 사용
- `Deserializer`는 JSON을 객체로 변환할 때 사용
- `@RequestBody`로 전달되는 JSON 데이터를 객체로 변환할 때 사용
- `@ResponseBody`, `@RestController`로 응답 데이터를 JSON으로 변환할 때 사용



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.mpc.springboot.member.application.dto.CreateMemberRequest;
import com.mpc.springboot.member.application.dto.MemberResponse;
import com.mpc.springboot.member.application.service.MemberService;
import com.mpc.springboot.member.domain.entity.Member;
import com.mpc.springboot.member.domain.vo.MemberCode;
import lombok.*;

Expand Down