[Spring] 스프링 부트를 이용한 게시판 프로젝트 - Repository, Dto 만들기!

전주은·2023년 1월 8일
0
post-thumbnail

Repository, Dto 만들기!

Repository

Querydsl

Querydsl을 맛보기 위해 인터페이스와 Impl 클래스를 만들어 보겠습니다.
게시글의 해시태그를 중복없이 리스트로 가져오는 쿼리문을 작성하겠습니다.

public interface ArticleRepositoryCustom {
    List<String> findAllDistinctHashtags();
}

public class ArticleRepositoryCustomImpl extends QuerydslRepositorySupport implements ArticleRepositoryCustom {
    public ArticleRepositoryCustomImpl() {
        super(Article.class);
    }

    // select distinct(hashtag) from article where hashtag is not null;
    @Override
    public List<String> findAllDistinctHashtags() {
        QArticle article = QArticle.article;
        return from(article)
                .distinct()
                .select(article.hashtag)
                .where(article.hashtag.isNotNull())
                .fetch();
    }
}

위 코드는 Querydsl을 사용하여 ArticleRepository에서 사용할 ArticleRepositoryCustom 인터페이스를 구현한 ArticleRepositoryCustomImpl 클래스 코드입니다.

ArticleRepositoryCustomImpl 클래스에서는 findAllDistinctHashtags 메소드를 오버라이드하여 사용합니다. 이 메소드는 Article 테이블에서 중복 없이 hashtag 필드를 모두 가져오는 쿼리를 수행합니다.

Querydsl을 사용하여 쿼리를 작성할 때는 Q도메인 클래스를 이용하여 엔티티와 필드를 지정합니다. Article 테이블에 대한 Q도메인 클래스는 QArticle입니다. 따라서 from(article)에서 article은 QArticle의 인스턴스입니다.

distinct()는 결과에서 중복된 값들을 제거해줍니다. select(article.hashtag)는 Article 테이블의 hashtag 필드만 선택합니다. where(article.hashtag.isNotNull())는 hashtag 필드가 null이 아닌 레코드만 선택합니다.

마지막으로 fetch()는 결과를 리스트로 반환합니다.

Querydsl
Querydsl은 Java 언어 기반의 타입 안정성을 제공하는 오픈소스 프레임워크입니다. SQL과 같은 쿼리 문장을 자바 코드로 작성하여 컴파일 단계에서 오류를 찾아내고, 쿼리 파라미터를 타입 안정적으로 처리할 수 있습니다.
Querydsl은 JPA, Hibernate, MyBatis 등 다양한 ORM 프레임워크와 호환되며, SQL, JPQL, MongoDB, Lucene 등 다양한 데이터 저장소를 지원합니다. 또한, 코드 자동완성 기능을 제공하여 개발자가 쿼리를 보다 쉽게 작성할 수 있도록 도와줍니다.

Querydsl의 주요 특징
1. 타입 안정성: 쿼리를 자바 코드로 작성하므로, 컴파일 단계에서 오류를 찾아내어 타입 안정성을 보장합니다.
2. 코드 자동완성: 코드 자동완성 기능을 제공하여 개발자가 쿼리를 보다 쉽게 작성할 수 있도록 도와줍니다.
3. ORM 프레임워크와의 호환성: JPA, Hibernate, MyBatis 등 다양한 ORM 프레임워크와 호환되며, 다양한 데이터 저장소를 지원합니다.
4. 다양한 쿼리 언어 지원: SQL, JPQL, MongoDB, Lucene 등 다양한 쿼리 언어를 지원합니다.
5. 확장성: Querydsl은 확장 가능한 구조를 가지고 있으며, 새로운 데이터 저장소나 쿼리 언어를 추가할 수 있습니다.

Querydsl은 이러한 특징을 바탕으로 데이터베이스 쿼리 작성 시 발생할 수 있는 문제점들을 해결하고, 개발자들이 보다 쉽게 쿼리를 작성할 수 있도록 도와줍니다.

ArticleRepositoty


@RepositoryRestResource
public interface ArticleRepository extends
        JpaRepository<Article, Long>,
        ArticleRepositoryCustom,
        QuerydslPredicateExecutor<Article>,
        QuerydslBinderCustomizer<QArticle> {

    Page<Article> findByTitleContaining(String title, Pageable pageable);
    Page<Article> findByContentContaining(String content, Pageable pageable);
    Page<Article> findByUserAccount_UserIdContaining(String userId, Pageable pageable);
    Page<Article> findByUserAccount_NicknameContaining(String nickname, Pageable pageable);
    Page<Article> findByHashtag(String hashtag, Pageable pageable);



    @Override
    default void customize(QuerydslBindings bindings, QArticle root){
        bindings.excludeUnlistedProperties(true);
        bindings.including(root.title, root.content, root.hashtag, root.createdAt, root.createdBy);
        bindings.bind(root.title).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.content).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.hashtag).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.createdAt).first(DateTimeExpression::eq);
        bindings.bind(root.createdBy).first(StringExpression::containsIgnoreCase);
    }
}

이 코드는 게시글(Article) 관련 Repository 인터페이스로, JpaRepository, QuerydslPredicateExecutor, QuerydslBinderCustomizer 인터페이스를 상속받고, ArticleRepositoryCustom 인터페이스를 구현합니다. JpaRepository는 스프링 데이터 JPA가 제공하는 인터페이스로, 기본적인 CRUD 메서드를 제공합니다. QuerydslPredicateExecutor 인터페이스는 Querydsl을 사용하여 동적 쿼리를 실행할 수 있도록 지원합니다. QuerydslBinderCustomizer 인터페이스는 Querydsl의 바인딩 커스터마이징을 지원합니다.

또한, @RepositoryRestResource 어노테이션을 사용하여 REST API 엔드포인트를 자동 생성합니다. 이 인터페이스에서는 게시글 검색 기능을 위한 메서드들을 선언하고 있습니다. 이 메서드들은 Spring Data JPA의 메서드 이름 규칙을 따르고 있어, 메서드 이름으로 검색 쿼리를 생성할 수 있습니다. customize() 메서드에서는 QuerydslBindings 객체를 사용하여 Querydsl 바인딩을 커스터마이징하고 있습니다. 이렇게 함으로써, REST API에서 Querydsl 바인딩이 적용된 동적 쿼리를 사용할 수 있게 됩니다.

ArticleCommentRepository


@RepositoryRestResource
public interface ArticleCommentRepository extends JpaRepository<ArticleComment, Long>,
        QuerydslPredicateExecutor<ArticleComment>,
        QuerydslBinderCustomizer<QArticleComment> {

    @Override
    default void customize(QuerydslBindings bindings, QArticleComment root){
        bindings.excludeUnlistedProperties(true);
        bindings.including(root.content, root.createdAt, root.createdBy);
        bindings.bind(root.content).first(StringExpression::containsIgnoreCase);
        bindings.bind(root.createdAt).first(DateTimeExpression::eq);
        bindings.bind(root.createdBy).first(StringExpression::containsIgnoreCase);
    }
}

이 코드는 Spring Data JPA의 JpaRepository를 상속하고 있으며, QuerydslPredicateExecutor와 QuerydslBinderCustomizer 인터페이스를 구현하고 있습니다.

QuerydslPredicateExecutor는 Spring Data JPA가 제공하는 인터페이스로, Querydsl을 이용해 동적으로 쿼리를 생성할 수 있게 해줍니다. 이 인터페이스를 구현하면, 제공하는 메서드를 사용하여 쿼리를 생성할 수 있습니다.

QuerydslBinderCustomizer는 QuerydslPredicateExecutor와 함께 사용되며, Spring Data REST에서 제공하는 HTTP API를 사용할 때 Querydsl을 이용하여 동적으로 쿼리를 생성할 수 있게 해줍니다. 이 인터페이스를 구현하면, customize() 메서드를 오버라이드하여 QuerydslBindings 객체를 사용하여 바인딩을 설정할 수 있습니다.

위 코드에서는 QuerydslBinderCustomizer를 구현하면서 customize() 메서드를 오버라이드하여 QuerydslBindings 객체를 사용하여 ArticleComment 엔티티의 content, createdAt, createdBy 속성에 대해 바인딩을 설정하고 있습니다. 이를 통해 Spring Data REST API에서 동적으로 쿼리를 생성할 수 있습니다.

Querydsl에서 바인딩하면 좋은점

  • 코드 간소화: QuerydslBinderCustomizer를 사용하면 기본적인 쿼리 조건을 한 번에 적용할 수 있으므로 코드가 간소화됩니다.
  • 유연성: 사용자는 자신의 쿼리 조건을 추가하거나 기본 쿼리 조건을 변경할 수 있습니다.
  • 안정성: 바인딩을 사용하면 사용자가 입력한 데이터를 쿼리에 적용하기 전에 데이터를 검증할 수 있습니다. 이를 통해 쿼리 에러를 방지할 수 있습니다.
  • 보안성: Querydsl 바인딩을 사용하면 일부 민감한 데이터를 숨길 수 있습니다. 즉, 사용자가 검색할 때 특정 필드를 검색하지 못하도록 할 수 있습니다.
    예를들어
public interface ArticleRepository extends JpaRepository<Article, Long>, QuerydslPredicateExecutor<Article>, QuerydslBinderCustomizer<QArticle> {
Page<Article> findByTitleContainingAndUserAccount_UserIdContaining(String title, String userId, Pageable pageable);

@Override
default void customize(QuerydslBindings bindings, QArticle root) {
    bindings.bind(root.title).first(StringExpression::containsIgnoreCase);
    bindings.bind(root.userAccount.userId).first(StringExpression::containsIgnoreCase);
}

}

여기에서, findByTitleContainingAndUserAccount_UserIdContaining 메서드는 더 이상 필요하지 않으며, 대신 Querydsl의 bindings 객체를 사용하여 검색 조건을 정의할 수 있습니다. 이렇게하면, 사용자가 입력한 값에 따라 동적으로 쿼리가 생성되므로, 코드의 중복을 줄이고 유지 보수성을 높일 수 있습니다.


### DTO(Req, dto, rep) 만들기
#### ArticleRequest: 글 작성/수정에 사용

```java
public record ArticleRequest(
        String title,
        String content,
        String hashtag
) {

    public static ArticleRequest of(String title, String content, String hashtag) {
        return new ArticleRequest(title, content, hashtag);
    }

    public ArticleDto toDto(UserAccountDto userAccountDto) {
        return ArticleDto.of(
                userAccountDto,
                title,
                content,
                hashtag
        );
    }
}

위 코드는 자바 16에서 새로 추가된 Record 타입을 사용하여 ArticleRequest DTO를 정의한 것입니다. Record는 데이터를 저장하는 데 사용되는 클래스를 간결하게 정의할 수 있게 해주는 기능으로, 클래스의 특정 목적이 데이터를 저장하고 전달하는 것이라면 Record를 사용하는 것이 더 효율적입니다.

위 코드에서는 제목(title), 내용(content), 해시태그(hashtag)를 저장하는 Record를 정의하였고, 이를 toDto() 메소드를 통해 ArticleDto로 변환할 수 있도록 하였습니다. 이때 toDto() 메소드는 UserAccountDto를 매개변수로 받아 ArticleDto를 생성하며, 이를 통해 사용자 정보와 함께 게시글 정보를 전달할 수 있습니다.

ArticleDto

public record ArticleDto(
        Long id,
        UserAccountDto userAccountDto,
        String title,
        String content,
        String hashtag,
        String createdBy,
        LocalDateTime createdAt,
        String modifiedBy,
        LocalDateTime modifiedAt
) {

    // 값 전달
    public static ArticleDto of(Long id, UserAccountDto userAccountDto, String title, String content, String hashtag, String createdBy, LocalDateTime createdAt, String modifiedBy, LocalDateTime modifiedAt){
        return new ArticleDto(id, userAccountDto, title, content, hashtag, createdBy, createdAt, modifiedBy, modifiedAt);
    }

    public static ArticleDto from(Article entity){
        return new ArticleDto(
                entity.getId(),
                UserAccountDto.from(entity.getUserAccount()),
                entity.getTitle(),
                entity.getContent(),
                entity.getHashtag(),
                entity.getCreatedBy(),
                entity.getCreatedAt(),
                entity.getModifiedBy(),
                entity.getModifiedAt()
        );
    }

    // 작성용 값전달 of
    public static ArticleDto of(UserAccountDto userAccountDto, String title, String content, String hashtag){
        return new ArticleDto(null, userAccountDto, title, content, hashtag, null, null, null, null);
    }

    public Article toEntity(UserAccount userAccount){
        return Article.of(
                userAccount,
                title,
                content,
                hashtag
        );
    }
}

record 키워드는 자바 14부터 도입된 기능으로, 클래스를 간단하게 정의할 수 있도록 도와줍니다. record 키워드를 사용하면 필드를 정의하고, 생성자와 접근자 메서드를 모두 간결하게 작성할 수 있습니다.

위 코드에서 ArticleDto 클래스는 Article 엔티티의 필드 중 일부를 포함하고 있습니다. from 메서드는 Article 엔티티 객체를 ArticleDto 객체로 변환하는 데 사용됩니다. toEntity 메서드는 ArticleRequest 객체를 Article 엔티티로 변환하는 데 사용됩니다.

of 메서드는 다른 메서드에서 객체를 생성할 때 사용됩니다. of 메서드는 다양한 방식으로 오버로딩되어 있습니다. 이를 사용하여 생성자에 필요한 매개변수를 전달하면 새 객체를 만들 수 있습니다.

이렇게 작성된 ArticleDto 클래스는 Article 엔티티를 다른 레이어에서 사용할 때 매우 편리합니다. ArticleDto 객체를 사용하면 엔티티 클래스를 직접 사용하는 대신 더 간결하고 명확한 코드를 작성할 수 있습니다.

Record에 대해 더 잘 알아보고 싶다면 클릭

ArticleCommentRequest


public record ArticleCommentRequest(Long articleId, String content) {
    public static ArticleCommentRequest of(Long articleId, String content) {
        return new ArticleCommentRequest(articleId, content);
    }

    public ArticleCommentDto toDto(UserAccountDto userAccountDto) {
        return ArticleCommentDto.of(
                articleId,
                userAccountDto,
                content
        );
    }
}

위 코드는 게시글 댓글 생성 시 요청하는 데이터를 담기 위한 DTO입니다.

record 키워드를 사용하여 클래스를 정의했습니다. record는 Java 14부터 도입된 기능으로, 불변(immutable) 데이터 객체를 간결하게 정의할 수 있게 해주는 문법입니다.

ArticleCommentRequest 클래스는 게시글 ID와 댓글 내용을 필드로 갖습니다. of 메서드는 생성자 대신 객체를 생성할 수 있는 정적 팩터리 메서드입니다.

toDto 메서드는 ArticleCommentRequest 객체를 ArticleCommentDto 객체로 변환하여 반환합니다. UserAccountDto를 매개변수로 받아 ArticleCommentDto 객체를 생성합니다. ArticleCommentDto 클래스는 게시글 댓글의 데이터를 담은 DTO입니다. of 메서드는 ArticleCommentDto 객체를 생성할 수 있는 정적 팩터리 메서드입니다.

이러한 DTO 클래스는 컨트롤러에서 클라이언트로부터 전송되는 요청(Request) 데이터나 서버에서 클라이언트로 전송하는 응답(Response) 데이터를 담는 데 사용됩니다. DTO 객체는 서로 다른 계층(Layer) 간의 데이터 교환을 위해 사용됩니다. 예를 들어, 컨트롤러(Controller)에서 서비스(Service) 계층으로 DTO 객체를 전달하거나, 서비스 계층에서 리포지토리(Repository) 계층으로 DTO 객체를 전달합니다.

ArticleCommentDto

public record ArticleCommentDto(
        Long id,
        Long articleId,
        UserAccountDto userAccountDto,
        String content,
        String createdBy,
        LocalDateTime createdAt,
        String modifiedBy,
        LocalDateTime modifiedAt
) {
    public static ArticleCommentDto of(Long id, Long articleId, UserAccountDto userAccountDto, String content, String createdBy, LocalDateTime createdAt, String modifiedBy, LocalDateTime modifiedAt){
        return new ArticleCommentDto(id, articleId, userAccountDto, content, createdBy, createdAt, modifiedBy, modifiedAt);
    }

    public static ArticleCommentDto of(Long articleId, UserAccountDto userAccountDto, String content) {
        return new ArticleCommentDto(null, articleId, userAccountDto, content, null, null, null, null);
    }

    public static ArticleCommentDto from(ArticleComment entity){
        return new ArticleCommentDto(
                entity.getId(),
                entity.getArticle().getId(),
                UserAccountDto.from(entity.getUserAccount()),
                entity.getContent(),
                entity.getCreatedBy(),
                entity.getCreatedAt(),
                entity.getModifiedBy(),
                entity.getModifiedAt()
        );
    }

    public ArticleComment toEntity(Article article, UserAccount userAccount){
        return ArticleComment.of(
                article,
                userAccount,
                content
        );
    }
}

위 코드는 게시글 댓글을 나타내는 ArticleComment의 DTO(Data Transfer Object) 클래스인 ArticleCommentDto입니다.

ArticleCommentDto는 ArticleComment 엔티티 클래스와 대응되는데, 엔티티 클래스는 데이터베이스에 저장되어 있는 게시글 댓글 정보를 담고 있는 클래스입니다. DTO 클래스는 엔티티 클래스의 데이터를 전송하기 적합한 형태로 변환하기 위해 사용됩니다.

ArticleCommentDto 클래스는 record 키워드를 사용하여 생성되었습니다. record 키워드는 Java 14부터 도입된 클래스 형태로, 불변(immutable) 데이터를 표현하기 위해 사용됩니다. 클래스의 속성을 final로 설정하지 않아도 됩니다. 또한, record 클래스는 자동으로 속성을 초기화하는 생성자와 equals(), hashCode(), toString() 메서드를 자동으로 생성해줍니다.

ArticleCommentDto 클래스에는 게시글 댓글의 정보를 담는 속성으로 id, articleId, userAccountDto, content, createdBy, createdAt, modifiedBy, modifiedAt가 있습니다. id는 댓글의 고유 식별자, articleId는 댓글이 달린 게시글의 식별자, userAccountDto는 댓글 작성자의 정보를 담는 DTO, content는 댓글 내용, createdBy는 댓글 작성자의 이름, createdAt는 댓글 작성 일시, modifiedBy는 댓글 수정자의 이름, modifiedAt는 댓글 수정 일시를 나타냅니다.

ArticleCommentDto 클래스는 of() 메서드를 제공하여, 엔티티에서 DTO로 변환할 때와 DTO에서 엔티티로 변환할 때 사용됩니다. from() 메서드는 엔티티 객체를 전달받아, DTO 객체를 생성합니다. toEntity() 메서드는 게시글 댓글을 생성하기 위해 사용됩니다. 게시글 댓글을 생성하기 위해서는 게시글 객체와 댓글 작성자 정보가 필요합니다. 따라서 toEntity() 메서드에서는 게시글 객체와 댓글 작성자 정보를 매개변수로 전달받아 ArticleComment 객체를 생성합니다.

ArticleResponse


public record ArticleResponse(
        Long id,
        String title,
        String content,
        String hashtag,
        LocalDateTime createdAt,
        String email,
        String nickname
) {
    public static ArticleResponse of(Long id, String title, String content, String hashtag, LocalDateTime createdAt, String email, String nickname){
        return new ArticleResponse(id, title, content, hashtag, createdAt, email, nickname);
    }

    public static ArticleResponse from(ArticleDto dto){
        String nickname = dto.userAccountDto().nickname();
        if (nickname == null || nickname.isBlank()){
            nickname = dto.userAccountDto().userId();
        }

        return new ArticleResponse(
                dto.id(),
                dto.title(),
                dto.content(),
                dto.hashtag(),
                dto.createdAt(),
                dto.userAccountDto().email(),
                nickname
        );
    }
}

이 코드는 게시글 정보를 전달하는 ArticleResponse 클래스를 정의하는 코드입니다.

ArticleResponse 클래스는 게시글의 ID, 제목, 내용, 해시태그, 작성일시, 작성자의 이메일, 작성자의 닉네임 정보를 포함하고 있습니다.

of 메서드는 ArticleResponse 객체를 생성합니다. from 메서드는 ArticleDto 객체를 ArticleResponse 객체로 변환합니다.

ArticleDto는 게시글 정보를 포함하고 있는 DTO 클래스입니다. ArticleDto의 userAccountDto 필드는 게시글 작성자의 계정 정보를 포함하고 있습니다. 이 정보는 ArticleResponse에서 작성자의 이메일과 닉네임을 가져오는 데 사용됩니다.

즉, 이 코드는 게시글 정보를 전달하는 데 사용되는 ArticleResponse 클래스를 정의하고, ArticleDto 객체를 이 클래스로 변환하는 데 사용되는 from 메서드를 제공합니다.

ArticleWithCommentsDto

public record ArticleWithCommentsDto(
        Long id,
        UserAccountDto userAccountDto,
        Set<ArticleCommentDto> articleCommentDtos,
        String title,
        String content,
        String hashtag,
        LocalDateTime createdAt,
        String createdBy,
        LocalDateTime modifiedAt,
        String modifiedBy
) {
    public static ArticleWithCommentsDto of(Long id, UserAccountDto userAccountDto, Set<ArticleCommentDto> articleCommentDtos, String title, String content, String hashtag, LocalDateTime createdAt, String createdBy, LocalDateTime modifiedAt, String modifiedBy){
        return new ArticleWithCommentsDto(id, userAccountDto, articleCommentDtos, title, content, hashtag, createdAt, createdBy, modifiedAt, modifiedBy);
    }

    public static ArticleWithCommentsDto from(Article entity){
        return new ArticleWithCommentsDto(
                entity.getId(),
                UserAccountDto.from(entity.getUserAccount()),
                entity.getArticleComments().stream()
                        .map(ArticleCommentDto::from)
                        .collect(Collectors.toCollection(LinkedHashSet::new)),
                entity.getTitle(),
                entity.getContent(),
                entity.getHashtag(),
                entity.getCreatedAt(),
                entity.getCreatedBy(),
                entity.getModifiedAt(),
                entity.getModifiedBy()
        );
    }

}

이 코드는 게시글(Article)과 그 게시글의 댓글(ArticleComment) 정보를 함께 담고 있는 DTO 클래스인 ArticleWithCommentsDto를 정의한 코드입니다.

ArticleWithCommentsDto 클래스는 게시글의 id, 작성자 정보(UserAccountDto), 댓글 정보(Set< ArticleCommentDto >), 제목, 내용, 해시태그, 생성일시, 생성자, 수정일시, 수정자 등을 담고 있습니다.

ArticleWithCommentsDto 클래스는 record 키워드를 사용하여 생성되었으며, of와 from 메소드를 정의하여 객체를 생성하고 변환할 수 있습니다. of 메소드는 매개변수를 이용하여 객체를 생성하고, from 메소드는 Entity 객체를 매개변수로 받아 DTO 객체로 변환하여 반환합니다. 또한 ArticleWithCommentsDto 클래스는 Article 엔티티를 이용하여 객체를 생성하는 from 메소드를 제공합니다. 이 메소드는 ArticleCommentDto 객체의 Set을 LinkedHashSet으로 변환하여 생성하고, UserAccountDto와 ArticleCommentDto 클래스의 from 메소드를 사용하여 UserAccountDto와 ArticleCommentDto 객체를 생성합니다. 이후 Article 엔티티의 정보를 이용하여 ArticleWithCommentsDto 객체를 생성하고 반환합니다.

ArticleWithCommentResponse

public record ArticleWithCommentResponse(
        Long id,
        String title,
        String content,
        String hashtag,
        LocalDateTime createdAt,
        String email,
        String nickname,
        Set<ArticleCommentResponse> articleCommentsResponses
) {
    public static ArticleWithCommentResponse of(Long id, String title, String content, String hashtag, LocalDateTime createdAt, String email, String nickname, Set<ArticleCommentResponse> articleCommentResponses){
        return new ArticleWithCommentResponse(id, title, content, hashtag, createdAt, email, nickname, articleCommentResponses);
    }

    public static ArticleWithCommentResponse from(ArticleWithCommentsDto dto){
        String nickname = dto.userAccountDto().nickname();
        if (nickname == null || nickname.isBlank()){
            nickname = dto.userAccountDto().userId();
        }

        return new ArticleWithCommentResponse(
                dto.id(),
                dto.title(),
                dto.content(),
                dto.hashtag(),
                dto.createdAt(),
                dto.userAccountDto().email(),
                nickname,
                dto.articleCommentDtos().stream().map(ArticleCommentResponse::from)
                        .collect(Collectors.toCollection(LinkedHashSet::new))
        );
    }
}

해당 코드는 게시글과 그에 따른 댓글 정보를 응답하는 데 사용되는 ArticleWithCommentResponse 클래스를 정의합니다. 이 클래스는 ArticleWithCommentsDto 객체에서 필요한 정보를 추출하여 생성됩니다.

ArticleWithCommentResponse 클래스는 다음과 같은 필드를 가지고 있습니다.

id: 게시글의 고유 ID
title: 게시글의 제목
content: 게시글의 내용
hashtag: 게시글의 해시태그
createdAt: 게시글의 작성 시간
email: 게시글 작성자의 이메일
nickname: 게시글 작성자의 닉네임
articleCommentsResponses: 게시글에 대한 댓글 목록
이 클래스는 다음과 같은 두 개의 메서드를 가지고 있습니다.

of(): ArticleWithCommentResponse 객체를 생성합니다.
from(): ArticleWithCommentsDto 객체를 사용하여 ArticleWithCommentResponse 객체를 생성합니다.

UserAccountDto

public record UserAccountDto(
        String userId,
        String userPassword,
        String email,
        String nickname,
        String memo,
        LocalDateTime createdAt,
        String createdBy,
        LocalDateTime modifiedAt,
        String modifiedBy
) {
    public static UserAccountDto of(String userId, String userPassword, String email, String nickname, String memo){
        return new UserAccountDto(userId, userPassword, email, nickname, memo, null, null, null, null);
    }

    public static UserAccountDto of(String userId, String userPassword, String email, String nickname, String memo, LocalDateTime createdAt, String createdBy, LocalDateTime modifiedAt, String modifiedBy){
        return new UserAccountDto(userId, userPassword, email, nickname, memo, createdAt, createdBy, modifiedAt, modifiedBy);
    }

    public static UserAccountDto from(UserAccount entity){
        return new UserAccountDto(
                entity.getUserId(),
                entity.getUserPassword(),
                entity.getEmail(),
                entity.getNickname(),
                entity.getMemo(),
                entity.getCreatedAt(),
                entity.getCreatedBy(),
                entity.getModifiedAt(),
                entity.getModifiedBy()
        );
    }

    public UserAccount toEntity(){
        return UserAccount.of(userId, userPassword, email, nickname, memo);
    }
}

위 코드는 UserAccountDto라는 record 클래스를 정의하고 있습니다. 이 클래스는 UserAccount 엔티티와 대응됩니다.

UserAccountDto 클래스는 UserAccount 엔티티의 필드를 그대로 가져와서 정의하고 있습니다. 이 필드에는 사용자 계정 정보를 저장하는데 필요한 userId, userPassword, email, nickname, memo 등이 포함됩니다.

클래스의 생성자는 userId, userPassword, email, nickname, memo, createdAt, createdBy, modifiedAt, modifiedBy를 매개변수로 받습니다. 생성자를 이용해서 UserAccountDto 객체를 생성할 수 있습니다. 만약 createdAt, createdBy, modifiedAt, modifiedBy를 생략하면 null 값으로 초기화됩니다.

of 메서드는 userId, userPassword, email, nickname, memo를 매개변수로 받아서 UserAccountDto 객체를 생성합니다.

from 메서드는 UserAccount 객체를 매개변수로 받아서 UserAccountDto 객체를 생성합니다. 이 메서드는 UserAccount 객체를 UserAccountDto 객체로 변환할 때 사용됩니다.

toEntity 메서드는 UserAccountDto 객체를 UserAccount 엔티티로 변환합니다. 이 메서드는 UserAccountDto 객체를 UserAccount 엔티티로 저장할 때 사용됩니다.

0개의 댓글