본문 바로가기
FrameWork/Spring

게시글 등록 화면

by 태윤2 2021. 8. 21.

css 는 화면을 그리는 역할을 하기 때문에 head
js는 화면이 다 그려진 뒤에 호출하는 것이 페이지 로딩속도를 높이는 방법이다.

 

{{>layout/header}}
<h1>스프링 부트로 시작하는 웹 서비스</h1>
</body>
{{>layout/footer}}
<!--{{>}}는 현재 머스테치 파일(index.mustache)을 기준으로 다른 파일을 가져옴-->

js 파일 경로

var main = {
    init: function () {
        var _this = this;
        $('#btn-save').on('click', function () {
            _this.save();
        });
    },
    save: function () {
        var data = {
            title: $('#title').val(),
            author: $('#author').val(),
            content: $('#content').val()
        };

        $.ajax({
            type: 'POST',
            url: '/api/v1/posts',
            dataType: 'json',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(data)
        }).done(function () {
            alert('글이 등록되었습니다.');
            window.location.href = '/';
        }).fail(function (error) {
            alert(JSON.stringify(error));
        });
    }
};

main.init();

여러 사람이 참여하는 프로젝트에서는 중복된 함수(function)이름은 자주 발생할 수 있음. 그래서 모든 function 이름을 확인하면서 만들 수는 없기 때문에 index.js만의 유효범위(scope)를 만들어서 사용

 

전체 조회 화면 만들기

<!--목록 출력 영역 -->
    <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>
  1. {{#posts}}
    1. posts 라는 List를 순회
    2. Java의 for문과 동일하게 생각
  2. {{id}} 등의 {{변수명}}
    1. List에서 뽑아낸 객체의 필드를 사용

Controller, Service, Repository 코드를 작성

기존에 있던 PostsRepository 인터페이스에 쿼리를 추가

public interface PostsRepository extends JpaRepository<Posts, Long> {

    // Query 가 가독성이 좋아 선택해서 사용.
    // Query 없이 SpringDataJpa 에서 제공하는 기본 메소드만으로도 해결 가능
    @Query("SELECT p from Posts p ORDER BY p.id DESC ")
    List<Posts> findAllDesc();
}

 

Entity 클래스만으로 처리가 어려운경우 조회용 프레임워크를 추가로 사용

  1. querydsl
  2. jooq
  3. MyBatis

Querydsl을 사용하는걸 추천하는데 그이유는

  1. 타입 안정성이 보장됨
    • 단순한 문자열로 쿼리를 생성하는 것이 아니라, 메소드를 기반으로 쿼리를 생성하기 때문에 오타나 존재하지 않는 컬럼명을 명시할 경우 IDE에서 자동으로 검출됨. 이 장점은 Jooq에서도 지원하는 장점이지만, MyBatis에서는 지원하지 않음
  2. 국내 많은 회사에서 사용중
    • 쿠팡,배민 등 JPA를 적극적으로 사용하는 회사에서는 Querydsl를 적극적으로 사용중
  3. 레퍼런스가 많음
    • 앞 2번의 장점에서 이어지는 것인데, 많은 회사와 개발자들이 사용하다보니 그만큼 국내 자료가 많음. 어떤 문제가 발생했을 때 여러 커뮤니티에 질문하고 그에대한 답변을 들을 수 있다는것은 큰 장점

PostsService에 코드를 추가

//readOnly = true 트랜잭션 범위는 유지, 조회 기능만 남겨두어 조회속도가 개선됨
//등록, 수정, 삭제 기능이 전혀 없는 메소드에서 사용하는 것을 추천
@Transactional(readOnly = true) 
public List<PostsListResponseDto> findAllDesc() {
        return postsRepository.findAllDesc()
                .stream()
                .map(PostsListResponseDto::new) // map(posts -> new PostsListResponseDto(posts)) 람다
                .collect(Collectors.toList());
}

위 코드와 같은 코드(Method Reference)

 

PostsListResponseDto 생성

@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 변경

@Controller
@RequiredArgsConstructor
public class IndexController {

    private final PostsService postsService;

    @GetMapping("/")
    public String index(Model model) {
        model.addAttribute("posts", postsService.findAllDesc());
        return "index";
    }

    @GetMapping("/posts/save")
    public String postsSave() {
        return "posts-save";
    }

}

 

 

  • 참고자료

              스프링 부트와 AWS로 혼자 구현하는 웹 서비스

'FrameWork > Spring' 카테고리의 다른 글

로그인 기능 개선  (0) 2021.08.21
스프링 시큐리티/ OAuth2.0 로그인 기능 구현  (0) 2021.08.21
머스테치  (0) 2021.08.21
JPA Auditing으로 생성시간/수정시간 자동화하기  (0) 2021.08.20
등록/수정/조회 API  (0) 2021.08.19