관리 메뉴

bright jazz music

blog07: 여러 글(list) 조회 본문

Projects/blog

blog07: 여러 글(list) 조회

bright jazz music 2023. 1. 2. 10:58
//PostController.java


@Slf4j
@RestController
@RequiredArgsConstructor
public class PostController {
    private final PostService postService;


    @PostMapping("/posts")
    public void post(@RequestBody @Valid PostCreate request) {
        postService.write(request);
//        return Map.of();
    }

    //단건 조회
    @GetMapping("/posts/{postId}")
    public PostResponse get(@PathVariable Long postId){

        PostResponse response = postService.get(postId);
        return response;
    }

    //여러 글 조회(글 목록 가져오기)
    //  /posts
    @GetMapping("/posts")
   public List<PostResponse> getList(){
        return postService.getList();
    }

}

 

 

//PostService.java

package com.endofma.blog.service;

import com.endofma.blog.domain.Post;
import com.endofma.blog.repository.PostRepository;
import com.endofma.blog.request.PostCreate;
import com.endofma.blog.response.PostResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service
//@RequiredArgsConstructor
public class PostService {

    private final PostRepository postRepository;
    public PostService(PostRepository postRepository){
        this.postRepository = postRepository;
    }

    public void write(PostCreate postCreate) {
        //PostCreate 일반 클래스 ==> Post 엔티티
        Post post = Post.builder()
                .title(postCreate.getTitle())
                .content(postCreate.getContent())
                .build();

        postRepository.save(post);
    }

    //단건 조회
    public PostResponse get(Long id) {

        Post post = postRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 글입니다.")); //있으면 post반환 없으면 에러 반환

        //응답 클래스를 분리
        return PostResponse.builder()
                .id(post.getId())
                .title(post.getTitle())
                .content(post.getContent())
                .build();

    }

//    public List<Post> getList() {
//        return postRepository.findAll();
//    }

    public List<PostResponse> getList(){
        return postRepository.findAll().stream()
//                .map(post -> PostResponse.builder().id(post.getId())
//                        .id(post.getId())
//                        .title(post.getTitle())
//                        .content(post.getContent())
//                        .build())
//                .collect(Collectors.toList())
// 값이 점점 많아질 수 있기 때문에  생성자를 통해서 해준다.

                .map(post -> new PostResponse(post))
                .collect(Collectors.toList());
    }
}

 

package com.endofma.blog.response;

import com.endofma.blog.domain.Post;
import lombok.Builder;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
 * 서비스 정책에 맞는 응답 클래스 (10글자)
 */

@Getter
//@Builder
public class PostResponse {
    private final Long id;
    private final String title;
    private final String content;

//    10글자 반환
//    public String getTitle(){
//        return this.title.substring(0, 10);
//        //이것보다는 생성자를 만들어서 빌더를 달아주자
//    }

    //생성자 오버로딩
    public PostResponse(Post post){
        this.id = post.getId();
        this.title = post.getTitle();
        this.content = post.getContent();
    }

    @Builder
    public PostResponse(Long id, String title, String content){
        this.id = id;
//        this.title = title.substring(0, 10); //10글자만 세팅된다. 입력값이 10자보다 적으면 오류가 발생한다.
        this.title = title.substring(0, Math.min(title.length(), 10)); //Math.min():입력받은 두 인자 중 작은 값 리턴.
        this.content = content;
    }
}

 

//PostServiceTest.java


import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@SpringBootTest
class PostServiceTest {

    @Autowired
    private PostService postService;

    @Autowired
    private PostRepository postRepository;

    @BeforeEach
    void clean(){
        postRepository.deleteAll();
    }

    @Test
    @DisplayName("글 작성")
    void test1() {
        //given
        PostCreate postCreate = PostCreate.builder()
                .title("제목입니다.")
                .content("내용입니다.")
                .build();

        //when
        postService.write(postCreate);

        //then
        Assertions.assertEquals(1L, postRepository.count());
        Post post = postRepository.findAll().get(0);
        assertEquals("제목입니다.", post.getTitle());
        assertEquals("내용입니다.", post.getContent());

    }

    @Test
    @DisplayName("글 1개 조회")
    void test2(){
        //given
        Post requestPost = Post.builder()
                .title("foo")
                .content("bar")
                .build();
        postRepository.save(requestPost);

        //when
        PostResponse response = postService.get(requestPost.getId());

        //then
        Assertions.assertNotNull(response);
        assertEquals(1L, postRepository.count());
        assertEquals("foo", response.getTitle());
        assertEquals("bar", response.getContent());
    }

    @Test
    @DisplayName("글 여러 개 조회")
    void test3(){
        //given
        postRepository.saveAll(List.of(
                Post.builder()
                        .title("foo1")
                        .content("bar1")
                        .build(),

                Post.builder()
                        .title("foo2")
                        .content("bar2")
                        .build()
        ));

//        postRepository.save(requestPost1);

//        Post requestPost2 = Post.builder()
//                .title("foo2")
//                .content("bar2")
//                .build();
//        postRepository.save(requestPost2);

        //when
        List<PostResponse> posts = postService.getList();

        //then
       assertEquals(2L, posts.size());


    }

}

 

//PostController.java

package com.endofma.blog.controller;

import com.endofma.blog.domain.Post;
import com.endofma.blog.request.PostCreate;
import com.endofma.blog.response.PostResponse;
import com.endofma.blog.service.PostService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@RestController
@RequiredArgsConstructor
public class PostController {
    private final PostService postService;


    @PostMapping("/posts")
    public void post(@RequestBody @Valid PostCreate request) {
        postService.write(request);
//        return Map.of();
    }

    //단건 조회
    @GetMapping("/posts/{postId}")
    public PostResponse get(@PathVariable Long postId){

        PostResponse response = postService.get(postId);
        return response;
    }

    //여러 글 조회(글 목록 가져오기)
    //  /posts
    @GetMapping("/posts")
   public List<PostResponse> getList(){
        return postService.getList();
    }

}

 

결과

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.7.6)

2023-01-02 12:43:29.422  INFO 24792 --- [    Test worker] c.e.blog.controller.PostControllerTest   : Starting PostControllerTest using Java 11.0.12 on DESKTOP-8H1PTVG with PID 24792 (started by markany-hjcha in D:\personal\blog)
2023-01-02 //...
2023-01-02 12:43:32.533  INFO 24792 --- [    Test worker] c.e.blog.controller.PostControllerTest   : Started PostControllerTest in 3.412 seconds (JVM running for 5.64)

MockHttpServletRequest:
      HTTP Method = GET
      Request URI = /posts
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8"]
             Body = null
    Session Attrs = {}

Handler:
             Type = com.endofma.blog.controller.PostController
           Method = com.endofma.blog.controller.PostController#getList()

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = [{"id":1,"title":"title_1","content":"content_1"},{"id":2,"title":"title_2","content":"content_2"}]
    Forwarded URL = null
   Redirected URL = null
          Cookies = []
2023-01-02 12:43:32.967  INFO 24792 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2023-01-02 12:43:32.967  INFO 24792 --- [ionShutdownHook] .SchemaDropperImpl$DelayedDropActionImpl : HHH000477: Starting delayed evictData of schema as part of SessionFactory shut-down'
2023-01-02 12:43:32.970  WARN 24792 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 90121, SQLState: 90121
2023-01-02 12:43:32.970 ERROR 24792 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper   : Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-214]
2023-01-02 12:43:32.970  WARN 24792 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 90121, SQLState: 90121
2023-01-02 12:43:32.970 ERROR 24792 --- [ionShutdownHook] o.h.engine.jdbc.spi.SqlExceptionHelper   : Database is already closed (to disable automatic closing at VM shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-214]
2023-01-02 12:43:32.970  WARN 24792 --- [ionShutdownHook] o.s.b.f.support.DisposableBeanAdapter    : Invocation of destroy method failed on bean with name 'entityManagerFactory': org.hibernate.exception.JDBCConnectionException: Unable to release JDBC Connection used for DDL execution
2023-01-02 12:43:32.971  INFO 24792 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2023-01-02 12:43:32.975  INFO 24792 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
BUILD SUCCESSFUL in 6s
4 actionable tasks: 1 executed, 3 up-to-date
PM 12:43:33: Execution finished ':test --tests "com.endofma.blog.controller.PostControllerTest.test5"'.

 

 

 

웹에서 테스트

#application.yml
spring:
  h2:
    console:
      enabled: true
      path: /h2-console

  datasource:
    url: jdbc:h2:mem:blog
    username: sa
    password:
    driver-class-name: org.h2.Driver

 

h2 디비 설정

 

값 집어넣고 조회

 

브라우저에서 확인하기

브라우저에서 글 여러 개 가져오는 것 조회

 

번외:

 

json formatter와 같은 확장 앱을 설치했기 때문에 위처럼 보이는 것임.

원래는 아래처럼 보임

 

Comments