DTO와 Repository란 무엇일까?
DTO(Data Transfer Object) : 계층 간에 데이터 교환을 위한 Java Bean이다.
Repository : Database에 CRUD 명령을 실행하게 만드는 Interface
(JpaRepository<Entity, PK>를 extends 하게 되면 CRUD를 사용할 수 있게 된다.)
BoardDto : 게시판 API 간에 Data를 전달하는 DTO
OAuthAttributes : OAuth2 Login을 통해서 가져온 OAuth2User의 정보를 담아주기 위한 DTO
shop.pingping2.board.dto.BoardDto.java
package shop.pingping2.board.dto;
import shop.pingping2.board.domain.Board; // Board Entity를 가져옴
import lombok.*;
import java.time.LocalDateTime;
// DTO : 데이터 전달 목적
// 데이터를 캡슐화한 데이터 전달 객체
@Getter
@Setter
@ToString // 객체가 가지고 있는 정보나 값들을 문자열로 만들어 리턴하는 메서드
@NoArgsConstructor // 인자 없이 객체 생성 가능
public class BoardDto {
private Long id;
private String writer;
private String title;
private String content;
private LocalDateTime createdDate;
private LocalDateTime modifiedDate;
public Board toEntity(){
Board board = Board.builder()
.id(id)
.writer(writer)
.title(title)
.content(content)
.build();
return board;
}
//
@Builder
public BoardDto(Long id, String title, String content, String writer, LocalDateTime createdDate, LocalDateTime modifiedDate) {
this.id = id;
this.writer = writer;
this.title = title;
this.content = content;
this.createdDate = createdDate;
this.modifiedDate = modifiedDate;
}
}
Lombok의 Builder 패턴을 이용하여 BoardDto를 생성한다.
1. @Builder 애노테이션으로 BoardDto 객체의 생성자 부분을 만들어주고
2. toEntity 메서드를 통해 Service -> Database(Entity)로 Data(게시판 글 상세 정보)를 전달할 때 Dto를 통해서 전달한다.
=> BoardDto 클래스는 @Builder 애노테이션으로 인해 builder() 메서드가 만들어지게 된 것이다.
shop.pingping2.board.dto.OAuthAttributes.java
package shop.pingping2.board.dto;
import lombok.Builder;
import lombok.Getter;
import shop.pingping2.board.domain.Role;
import shop.pingping2.board.domain.User;
import java.util.Map;
@Getter
public class OAuthAttributes {
private Map<String, Object> attributes;
private String nameAttributeKey;
private String name;
private String email;
private String picture;
@Builder
public OAuthAttributes(Map<String, Object> attributes,
String nameAttributeKey,
String name,
String email,
String picture) {
this.attributes = attributes;
this.nameAttributeKey = nameAttributeKey;
this.name = name;
this.email = email;
this.picture = picture;
}
public static OAuthAttributes of(String registrationId,
String userNameAttributeName,
Map<String, Object> attributes) {
return ofGoogle(userNameAttributeName, attributes);
}
public static OAuthAttributes ofGoogle(String userNameAttributeName, Map<String, Object> attributes) {
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email((String) attributes.get("email"))
.picture((String) attributes.get("picture"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
public User toEntity() {
return User.builder()
.name(name)
.email(email)
.picture(picture)
.role(Role.GUEST)
.build();
}
}
public static OAuthAttributes of(String registrationId,
String userNameAttributeName,
Map<String, Object> attributes) {
return ofGoogle(userNameAttributeName, attributes);
}
'OauthAttributes' Class의 static Method임을 의미하며
Static Method는 별도 객체의 호출 없이 사용 가능하도록 하기 위한 목적을 지니고 있다.
of란 Custom method를 정의하며, Arguments로 3개를 받는다.
Return value로는 ofGoogle Method를 호출한 값을 받게 된다.
public static OAuthAttributes ofGoogle(String userNameAttributeName, Map<String, Object> attributes) {
return OAuthAttributes.builder()
.name((String) attributes.get("name"))
.email((String) attributes.get("email"))
.picture((String) attributes.get("picture"))
.attributes(attributes)
.nameAttributeKey(userNameAttributeName)
.build();
}
이 또한 OAuthAttributes 클래스의 정적 메서드를 선언하는 부분이다.
public User toEntity() {
return User.builder()
.name(name)
.email(email)
.picture(picture)
.role(Role.GUEST)
.build();
}
toEntity 메서드를 통해 Service -> Database(Entity)로 Data를 전달할 때 Dto를 통해서 전달한다.
(( CustomOAuth2UserService 부분 ))
shop.pingping2.board.repository.BoardRepository.java
package shop.pingping2.board.repository;
import shop.pingping2.board.domain.Board;
import org.springframework.data.jpa.repository.JpaRepository;
import shop.pingping2.board.domain.User;
import java.util.List;
// JpaRepository<Entity 클래스, PK 타입>
public interface BoardRepository extends JpaRepository<Board, Long> {
List<Board> findByTitleContaining(String keyword);
Board findByUser(User user);
}
Interface는 '규격'으로의 역할을 한다.
JpaRepository : Entity의 CRUD가 가능하도록 JpaRepository 인터페이스를 제공하며, 상속해주기만 하면 된다.
아래의 형태로 사용한다.
JpaRepository<Entity 클래스, PK 타입>
=> Entity Class가 Board이며, Primary Key의 Type은 Long임을 의미한다.
shop.pingping2.board.repository.UserRepository.java
package shop.pingping2.board.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import shop.pingping2.board.domain.User;
import javax.persistence.EntityManager;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public interface UserRepository extends JpaRepository<User,Long> {
Optional<User> findByEmail(String email); // 이미 email을 통해 생성된 사용자인지 체크
}
다음 글에서는 Service -> Config 설정 부분 및 SpringSecurity 부분을 확인할 예정이다.
그 이후에는 application.yml 부분 세팅에 대해 다시 확인해보고 Application 실행 및 DB에 값이 저장되는지 등을 확인해 볼 예정이다.
'Programming > SpringBoot' 카테고리의 다른 글
[SpringBoot] 간단한 게시판 만들기 #6 - SpringSecurity 개념 및 구현 (2) | 2022.01.03 |
---|---|
[SpringBoot] 간단한 게시판 만들기 #5 - Service 구현 (0) | 2022.01.03 |
[SpringBoot] 간단한 게시판 만들기 #3 - domain(Entity) 구현 (0) | 2022.01.03 |
[SpringBoot] 간단한 게시판 만들기 #2 - Controller 구현 (1) | 2022.01.03 |
[SpringBoot] 간단한 게시판 만들기 #1 - 세팅 (3) | 2021.12.30 |