
1. VO(Value Object)
- 값 객체 : 속성이나 필드를 가지고 있는 객체
- 불변(immutable)하게 설계
- 불변성(Immutable) : 한 번 생성되면 내부 상태가 변경되지 않음
- 등가성(Equality)값 객체는 내부 속성의 값이 동일하면 동일한 것으로 간주
- 값 기반(Value-based)값 객체는 주로 속성 값 기반, 식별자에 의존하지 않음



2. build.gradle에 정리하기
dependencies {
// 서드파티
implementation group: 'com.auth0', name: 'java-jwt', version: '4.3.0'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.0'
implementation 'org.springframework.boot:spring-boot-starter-aop'
implementation group: 'org.qlrm', name: 'qlrm', version: '4.0.1'
implementation group: 'org.mindrot', name: 'jbcrypt', version: '0.4'
// 기본
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-mustache'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
3. 세션을 관리하는 CLASS 만들기
package shop.mtcoding.blog.user;
import lombok.Data;
import java.sql.Timestamp;
@Data
public class SessionUser {
private Integer id;
private String username;
private String password;
private String email;
private Timestamp createdAt;
public SessionUser(User user) {
this.id = user.getId();
this.username = user.getUsername();
this.password = user.getPassword();
this.email = user.getEmail();
this.createdAt = user.getCreatedAt();
}
}
- 서비스에서 수정하기
@Transactional
public SessionUser 회원수정(int id, UserRequest.UpdateDTO reqDTO){
User user = userJPARepository.findById(id)
.orElseThrow(() -> new Exception404("회원정보를 찾을 수 없습니다"));
user.setPassword(reqDTO.getPassword());
user.setEmail(reqDTO.getEmail());
return new SessionUser(user);
} // 더티체킹
public SessionUser 로그인(UserRequest.LoginDTO reqDTO){
User user = userJPARepository.findByUsernameAndPassword(reqDTO.getUsername(), reqDTO.getPassword())
.orElseThrow(() -> new Exception401("인증되지 않았습니다"));
return new SessionUser(user);
}
- newSessionUser : VO
- 섹션에 저장한 객체가 다라짐 / User -> SessionUser
@PutMapping("/api/users/{id}")
public ResponseEntity<?> update(@PathVariable Integer id, @RequestBody UserRequest.UpdateDTO reqDTO) {
SessionUser sessionUser = (SessionUser) session.getAttribute("sessionUser");
SessionUser newSessionUser = userService.회원수정(sessionUser.getId(), reqDTO);
session.setAttribute("sessionUser", newSessionUser);
// 이 친구만 DTO 생성위치 예외
return ResponseEntity.ok(new ApiUtil(newSessionUser));
}
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody UserRequest.LoginDTO reqDTO) {
SessionUser sessionUser = userService.로그인(reqDTO); // 섹션에 저장한 객체가 다라짐 User -> SessionUser
session.setAttribute("sessionUser", sessionUser);
return ResponseEntity.ok(new ApiUtil(null));
// USER는 모든 객체의 부모라 괜찮음 -> 연관된 객체가 없음
// 연관된 객체가 있다면
}
4. DTO 전략 세우기
- 기본 DTO를 만들어서 공통된 DTO에서 사용하기
- 달라지는 내용은 추가로 DTO 만들어 사용하기

- 기본DTO : 연관된 정보를 제외하고 기본데이터로 만들기
Share article