Back-End/Springboot와 AWS로 혼자 구현하는 웹 서비스

Chapter 04. 머스테치로 화면 구성하기 (4)

yeonx 2022. 3. 16. 23:37
728x90

4.4 전체 조회 화면 만들기

 

index.mustache

{{>layout/header}}
    <h1>스프링 부트로 시작하는 웹 서비스 Ver.2 </h1>
    <div class="col-md-12">
        <div class="row">
            <div class="col-md-6">
                <a href="/posts/save" role="button" class="btn btn-primary">글 등록</a>
            </div>
        </div>
        <br>
        <!--목록 출력 영역-->
        <table class="table table-horizontal table-bordered">
            <thead class="thead-strong">
            <tr>
                <th>게시글번호</th>
                <th>제목</th>
                <th>작성자</th>
                <th>최종수정일</th>
            </tr>
            </thead>
            <tbody id="tbody">
            {{#posts}}
                <tr>
                    <td>{{id}}</td>
                    <td>{{title}}</td>
                    <td>{{author}}</td>
                    <td>{{modifiedDate}}</td>
                </tr>
            {{/posts}}
            </tbody>
        </table>
    </div>
{{>layout/footer}}
① {{#posts}}
 - posts라는 List를 순화
 - Java의 for문과 동일하게 생각하면 됨

② {{id}} 등의 {{변수명}}
 - List에서 뽑아낸 객체의 필드를 사용

여기서 머스테치의 문법이 처음으로 사용된다.

 


PostsRepository.java

package com.jojoldu.book.springboot.domain.posts;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface PostsRepository extends JpaRepository<Posts,Long> {
    @Query("SELECT p FROM Posts p ORDER BY p.id DESC")
    List<Posts> findAllDesc();
}

- @Query는 가독성이 좋음

 


규모가 있는 프로젝트에서의 데이터 조회는 FK의 조인, 복잡한 조건 등으로 인해 이런 Entity 클래스만으로 처리하기 어려워 조회용 프레임 워크를 추가로 사용함. -> 대표적으로 querydsl, jooq, MyBatis 등이 있음

여기서 querydsl가 추천되는 이유

1. 타입 안정성이 보장된다

단순한 문자열로 쿼리를 생성하는 것이 아니라, 메소드를 기반으로 쿼리를 생성하기 때문에 오타나 존재하지 않는 컬럼명을 명시할 경우 IDE에서 자동으로 검출됨. (이 장점은 Jooq에서도 지원하는 장점이지만, MyBatis에서는 지원하지 않음)

2. 국내 많은 회사에서 사용 중

쿠팡, 배민 등 JPA를 적극적으로 사용하는 회사에서는 Querydsl를 적극적으로 사용중

3. 레퍼런스가 많다.

많은 회사와 개발자들이 사용하다보니 그만큼 국내 자료가 많다. 어떤 문제가 발생했을 때 여러 커뮤니티에 질문하고 그에 대한 답변을 들을 수 있다는 것은 큰 장점이다.


PostsService.java

@Transactional(readOnly = true)
public List<PostsListResponseDto> findAllDesc(){
    return postsRepository.findAllDesc().stream()
            .map(PostsListResponseDto::new)
            .collect(Collectors.toList());
}

다음 코드를 넣는다.

 

findAllDesc 메소드의 트랜잭션 어노테이션(@Transactional)에 옵션이 하나 추가되었음.

(readOnly=true)를 주면 트랜잭션 범위는 유지하되, 조회 기능만 남겨두어 조회 속도가 개선되기 때문에 등록, 수정, 삭제 기능이 전혀 없는 서비스 메소드에서 사용하는 것을 추천

.map(PostsListResponseDto::new)

이 코드는 실제로 다음과 같다.

.map(posts -> new PostsListResponseDto(posts))

postsRepository 결과로 넘어온 Posts의 Stream을 map을 통해 PostsListResponseDto 변환 -> List로 반환하는 메소드

 


PostsListResponseDto.java

import com.jojoldu.book.springboot.domain.posts.Posts;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class PostsListResponseDto {
    private Long id;
    private String title;
    private  String author;
    private LocalDateTime modifiedDate;

    public PostsListResponseDto(Posts entity){
        this.id = entity.getId();
        this.title = entity.getTitle();
        this.author=entity.getAuthor();
        this.modifiedDate=entity.getModifiedDate();
    }
}

 

IndexController.java

private final PostsService postsService;

    @GetMapping("/")
    public String index(Model model){
        model.addAttribute("posts",postsService.findAllDesc());
        return "index";
    }
① Model
 - 서버 템플릿 엔진에서 사용할 수 있는 객체를 저장할 수 있음
 - 여기서는 postsService.findAllDesc()로 가져온 결과로 posts로 index.mustache에 전달

 

이제 글을 등록하고 조회해보자

 

조회목록

 

 

출처 : 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 [이동욱 지음]