1. Dto에서 Entity로 변환
UserEntity
package com.basic.GADI.entity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;
import java.util.List;
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@DynamicInsert
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
@Column(nullable = false)
private String userName;
@Column(unique = true)
private String userEmail;
@Column(nullable = false)
private String userPw;
private String userFile;
@Column(nullable = false)
@ColumnDefault("'U'")
private String userRole;
@OneToMany(mappedBy = "user")
private List<Favorites> favorites;
}
회원가입 처리를 위한 Dto ( RegisterRequestDto )
package com.basic.GADI.dto.request;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RegisterRequestDto {
@NotBlank(message = "아이디는 필수 입력 값입니다.")
@Pattern(regexp = "^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$", message = "아이디는 이메일 형식입니다.")
private String userEmail;
@NotBlank(message = "이름은 필수 입력 값입니다.")
private String userName;
@NotBlank(message = "비밀번호는 필수 입력 값입니다.")
@Pattern(regexp = "^[A-Za-z0-9]{6,12}$", message = "비밀번호는 숫자, 문자 포함의 6~12자리로 입력해주세요.")
private String userPw;
@Pattern(regexp = "^010-[0-9]{4}-[0-9]{4}$", message = "전화번호 형식은 010-1234-5678 입니다.")
private String userPhone;
@Pattern(regexp = "^(19\\d{2}|20\\d{2})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$", message = "생년월일 형식은 YYYY-MM-DD 입니다.")
private String userBirth;
}
기존 AuthService 에서 Dto를 Entity로 변환하기 위해 builder를 사용해서 넣어주었다.
AuthService
User registerUser = User.builder()
.userEmail(registerRequestDto.getUserEmail())
.userName(registerRequestDto.getUserName())
.userPw(passwordEncoder.encode(registerRequestDto.getUserPw()))
.build();
userRepository.save(registerUser);
-> 서비스단에 코드가 길어짐
-> 좀 더 간결하게 하기 위해 Dto를 Entity로 변환하는 코드를 Dto 내부에 메서드로 만들어 준다.
1) 생성자 사용
UserEntity에 필요한 변수의 생성자를 추가해준다.
// toRegisterRequestDto()에서 사용하기 위한 생성자
public User(String userEmail, String userName,
String userPw, String userPhone, String userBirth) {
this.userEmail = userEmail;
this.userName = userName;
this.userPw = userPw;
this.userPhone = userPhone;
this.userBirth = userBirth;
RegisterRequestDto에 toRegisterRequestDto() 메서드 생성
public User toEntity(String encodedPw) {
return new User(
this.userEmail,
this.userName,
encodedPw,
this.userPhone,
this.userBirth
);
}
2) 그대로 builder 사용
RegisterRequestDto 에 toRegisterRequestDto(String encodedPw) 메서드 생성
// Dto 에서 Entity 로 변환
public User toRegisterRequestDto(String encodedPw) {
return User.builder()
.userEmail(userEmail)
.userName(userName)
.userPw(encodedPw)
.userPhone(userPhone)
.userBirth(userBirth)
.build();
}
AuthService
String encodedPw = passwordEncoder.encode(registerRequestDto.getUserPw());
User registerUser = registerRequestDto.toRegisterRequestDto(encodedPw);
userRepository.save(registerUser);
2. Entity에서 Dto로 변환
기존 코드 - UserService
public MyInfoResponseDto findMyInfo(Long userId) {
Optional<User> findUserOne = userRepository.findById(userId);
if (findUserOne.isEmpty()) {
throw new BusinessException("해당 사용자를 찾을 수 없습니다.", HttpStatus.NOT_FOUND);
}
MyInfoResponseDto responseDto = new MyInfoResponseDto();
responseDto.setUserName(findUserOne.get().getUserName());
responseDto.setUserEmail(findUserOne.get().getUserEmail());
responseDto.setUserFile(findUserOne.get().getUserFile());
responseDto.setUserPhone(findUserOne.get().getUserPhone());
responseDto.setUserBirth(findUserOne.get().getUserBirth());
return responseDto;
}
1) MyInfoResponseDto - 정적 메서드 방식 : 간결한 변환
// User Entity 에서 Dto 로 변환
public static MyInfoResponseDto fromUser(User user) {
return new MyInfoResponseDto(
user.getUserName(),
user.getUserEmail(),
user.getUserFile(),
user.getUserPhone(),
user.getUserBirth()
);
}
메서드 생성 후 UserService
public MyInfoResponseDto findMyInfo(Long userId) {
Optional<User> findUserOne = userRepository.findById(userId);
if (findUserOne.isEmpty()) {
throw new BusinessException("해당 사용자를 찾을 수 없습니다.", HttpStatus.NOT_FOUND);
}
return MyInfoResponseDto.fromUser(findUserOne.get());
}
2) builder 사용 방식 : 가독성과 유지보수에 좋음
public static MyInfoResponseDto fromUser(User user) {
return MyInfoResponseDto.builder()
.userName(user.getUserName())
.userEmail(user.getUserEmail())
.userFile(user.getUserFile())
.userPhone(user.getUserPhone())
.userBirth(user.getUserBirth())
.build();
}
📌 @Builder 패턴이 뭐야?
👉 객체를 생성할 때 필드 값을 유연하게 설정할 수 있도록 도와주는 패턴
👉 생성자의 단점을 보완하고, 가독성과 유지보수를 쉽게 해줌
🚀 @Builder를 쓰는 이유 (왜 필요할까?)
- 필드가 많으면 생성자 호출이 헷갈림
User user1 = new User("test@email.com", "홍길동", "1234", "010-1234-5678", "2000-01-01");
User user2 = new User("test2@email.com", "이순신", "5678", "010-5678-1234", "1995-05-05");
✅ 필드 순서를 맞춰야 해서 어떤 값이 어떤 필드인지 헷갈릴 수 있음!
- 필드가 많으면 setter()로 하나하나 설정하는 것도 귀찮음
User user = new User();
user.setUserEmail("test@email.com");
user.setUserName("홍길동");
user.setUserPw("1234");
user.setUserPhone("010-1234-5678");
user.setUserBirth("2000-01-01");
✅ 코드가 길어지고 객체가 불변(immutable)하지 않음
✅ @Builder 사용하면 이렇게 깔끔해짐!
User user = User.builder()
.userEmail("test@email.com")
.userName("홍길동")
.userPw("1234")
.userPhone("010-1234-5678")
.userBirth("2000-01-01")
.build();
✔ 필드 순서를 신경 쓰지 않아도 됨
✔ 가독성이 좋아짐
✔ 객체가 불변(immutable)하게 유지됨
'공부할 것 !' 카테고리의 다른 글
[오류] 415 (Unsupported Media Type) (0) | 2024.09.23 |
---|---|
[오류] java.lang.IllegalStateException (0) | 2024.09.20 |
chart.js를 이용해 데이터 시각화하기 (0) | 2024.08.23 |
AOP (0) | 2024.08.22 |
Maven, 형상관리 (0) | 2024.08.20 |