Mary's log 2024. 10. 20. 00:48

 

 

com.jojoldu.springboot.service.posts \ class PostsService.java

com.jojoldu.springboot.web.dto \ class PostsSaveRequestDto.java

com.jojoldu.springboot.web \ class PostsApiController.java

 

 

 

PostApiController.java  -  save 함수 빨강색은 아직 PostsService에 함수가 없어서 그럼. 작성해줄 거임. (책 순서가 전부 이런 순서다..)

package com.jojoldu.springboot.web;

import lombok.RequiredArgsConstructor;
import com.jojoldu.springboot.service.posts.PostsService;
import com.jojoldu.springboot.web.dto.PostsSaveRequestDto;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController
public class PostsApiController {

    private final PostsService postsService;

    @PostMapping("/api/v1/posts")
    public Long save(@RequestBody PostsSaveRequestDto requestDto) {
        return postsService.save(requestDto);
    }

}

 

PostsService.java - toEntity 빨강색은 아직 PostsSaveRequestDto.java에 없어서 그렇다. 작성해주러감. (책 순서가 전부 이런 순서다..)

package com.jojoldu.springboot.service.posts;

import com.jojoldu.springboot.domain.posts.PostsRepository;
import com.jojoldu.springboot.web.dto.PostsSaveRequestDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Service
public class PostsService {

    private final PostsRepository postsRepository;

    @Transactional
    public Long save(PostsSaveRequestDto requestDto) {
        return postsRepository.save(requestDto.toEntity()).getId();
    }

}

 

PostsSaveRequestDto.java

package com.jojoldu.springboot.web.dto;

import com.jojoldu.springboot.domain.posts.Posts;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class PostsSaveRequestDto {
    private String title;
    private String content;
    private String author;

    @Builder
    public PostsSaveRequestDto(String title, String content, String author) {
        this.title=title;
        this.content=content;
        this.author=author;
    }

    public Posts toEntity() {
        return Posts.builder()
                .title(title)
                .content(content)
                .author(author)
                .build();
    }
}

 

 

main 클래스들은 적었으니, test 에도 작성하러감.


src.test.java.com.jojoldu.springboot.web \ class PostsApiControllerTest.java   생성

package com.jojoldu.springboot.web;

import com.jojoldu.springboot.domain.posts.Posts;
import com.jojoldu.springboot.domain.posts.PostsRepository;
import com.jojoldu.springboot.web.dto.PostsSaveRequestDto;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PostsApiControllerTest {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private PostsRepository postsRepository;

    @After
    public void tearDown() throws Exception {
        postsRepository.deleteAll();
    }

    @Test
    public void registerPosts() throws Exception {
        String title = "title";
        String content = "content";
        PostsSaveRequestDto requestDto = PostsSaveRequestDto.builder()
                                                            .title(title)
                                                            .content(content)
                                                            .author("author")
                                                            .build();
        String url = "http://localhost:" + port + "/api/v1/posts";

        ResponseEntity<Long> responseEntity = restTemplate.postForEntity(url, requestDto, Long.class);

        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isGreaterThan(0L);

        List<Posts> all = postsRepository.findAll();
        assertThat(all.get(0).getTitle()).isEqualTo(title);
        assertThat(all.get(0).getContent()).isEqualTo(content);
    }

}

 

@Test 어노테이션이 달린 함수 좌측 ▷ 실행.

 

test 에서 문제 없음을 확인. 이제 main의 PostApiController에 요청 주소 추가하기 위한 세팅하러감.

 


src/main/java/com/jojoldu/springboot/web/dto/ class PostsUpdateRequestDto.java  생성

package com.jojoldu.springboot.web.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class PostsUpdateRequestDto {
    private String title;
    private String content;

    @Builder
    public PostsUpdateRequestDto(String title, String content) {
        this.title = title;
        this.content=content;
    }
}

 

src/main/java/com/jojoldu/springboot/domain/posts/ class Posts.java  - update 함수 추가

package com.jojoldu.springboot.web.dto;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Getter // lombok
@NoArgsConstructor
@Entity // for JPA
public class Posts {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(length = 500, nullable = false)
    private String title;

    @Column(columnDefinition = "TEXT", nullable = false)
    private String content;

    private String author;

    @Builder
    public Posts(String title, String content, String author) {
        this.title = title;
        this.content = content;
        this.author = author;
    }

    public void update(String title, String content) {
        this.title = title;
        this.content = content;
    }
}

 

src/main/java/com/jojoldu/springboot/service/posts/ class PostsService.java  - update, findById 함수 추가

package com.jojoldu.springboot.service.posts;

import com.jojoldu.springboot.domain.posts.Posts;
import com.jojoldu.springboot.domain.posts.PostsRepository;
import com.jojoldu.springboot.web.dto.PostsResponseDto;
import com.jojoldu.springboot.web.dto.PostsSaveRequestDto;
import com.jojoldu.springboot.web.dto.PostsUpdateRequestDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

@RequiredArgsConstructor
@Service
public class PostsService {

    private final PostsRepository postsRepository;

    @Transactional
    public Long save(PostsSaveRequestDto requestDto) {
        return postsRepository.save(requestDto.toEntity()).getId();
    }

    @Transactional
    public Long update(Long id, PostsUpdateRequestDto requestDto) {
        Posts posts = postsRepository.findById(id).orElseThrow(()-> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id));
        posts.update(requestDto.getTitle(), requestDto.getContent());
        return id;
    }

    @Transactional
    public PostsResponseDto findById(Long id) {
        Posts entity = postsRepository.findById(id).orElseThrow(()-> new IllegalArgumentException(("해당 게시글이 없습니다. id=" + id)));
        return new PostsResponseDto(entity);
    }
}

 

src/main/java/com/jojoldu/springboot/web/ class PostsApiController.java  - update, findById 매핑주소 추가

 

package com.jojoldu.springboot.web;

import com.jojoldu.springboot.web.dto.PostsResponseDto;
import com.jojoldu.springboot.web.dto.PostsUpdateRequestDto;
import lombok.RequiredArgsConstructor;
import com.jojoldu.springboot.service.posts.PostsService;
import com.jojoldu.springboot.web.dto.PostsSaveRequestDto;
import org.springframework.web.bind.annotation.*;

@RequiredArgsConstructor
@RestController
public class PostsApiController {

    private final PostsService postsService;

    @PostMapping("/api/v1/posts")
    public Long save(@RequestBody PostsSaveRequestDto requestDto) {
        return postsService.save(requestDto);
    }

    @PutMapping("/api/v1/posts/{id}")
    public Long update(@PathVariable Long id, @RequestBody PostsUpdateRequestDto requestDto) {
        return postsService.update(id, requestDto);
    }

    @GetMapping("/api/v1/posts/{id}")
    public PostsResponseDto findById(@PathVariable Long id) {
        return postsService.findById(id);
    }

}

 

 

 

 

 


test 의  PostApiControllerTest.java에도 update 함수 추가해서 테스트해보기.

 

test/java/com/jojoldu/springboot/web / PostsApiControllerTest.java - update 함수 추가

package com.jojoldu.springboot.web;

import com.jojoldu.springboot.domain.posts.Posts;
import com.jojoldu.springboot.domain.posts.PostsRepository;
import com.jojoldu.springboot.web.dto.PostsSaveRequestDto;
import com.jojoldu.springboot.web.dto.PostsUpdateRequestDto;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PostsApiControllerTest {

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private PostsRepository postsRepository;

    @After
    public void tearDown() throws Exception {
        postsRepository.deleteAll();
    }

    @Test
    public void registerPosts() throws Exception {
        String title = "title";
        String content = "content";
        PostsSaveRequestDto requestDto = PostsSaveRequestDto.builder()
                                                            .title(title)
                                                            .content(content)
                                                            .author("author")
                                                            .build();
        String url = "http://localhost:" + port + "/api/v1/posts";

        ResponseEntity<Long> responseEntity = restTemplate.postForEntity(url, requestDto, Long.class);

        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isGreaterThan(0L);

        List<Posts> all = postsRepository.findAll();
        assertThat(all.get(0).getTitle()).isEqualTo(title);
        assertThat(all.get(0).getContent()).isEqualTo(content);
    }

    @Test
    public void updatePosts() throws Exception {
        Posts savedPosts = postsRepository.save(Posts.builder()
                                                    .title("title")
                                                    .content("content")
                                                    .author("author")
                                                    .build());
        Long updateId = savedPosts.getId();
        String expectedTitle = "title2";
        String expectedContent = "content2";

        PostsUpdateRequestDto requestDto = PostsUpdateRequestDto.builder()
                                                                .title(expectedTitle)
                                                                .content(expectedContent)
                                                                .build();

        String url = "http://localhost:" + port + "/api/v1/posts/" + updateId;

        HttpEntity<PostsUpdateRequestDto> requestEntity = new HttpEntity<>(requestDto);

        ResponseEntity<Long> responseEntity = restTemplate.exchange(url, HttpMethod.PUT, requestEntity, Long.class);

        assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(responseEntity.getBody()).isGreaterThan(0L);

        List<Posts> all = postsRepository.findAll();
        assertThat(all.get(0).getTitle()).isEqualTo(expectedTitle);
        assertThat(all.get(0).getContent()).isEqualTo(expectedContent);
    }

}

 

@Test 어노테이션이 붙은

updatePosts 함수 좌측 ▷ 실행.

 

오류 없이 성공.

 


h2 웹 콘솔에서 '데이터 수정'함수가 정상적으로 반영되는지,  확인하는 설정 추가하기

 

src/main/resources/application.properties

 

# jpa sql show setting
spring.jpa.show_sql=true

# h2 : create table - id setting
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
spring.jpa.properties.hibernate.dialect.storage_engine=innodb
spring.datasource.hikari.jdbc-url=jdbc:h2:mem://localhost/~/testdb;MODE=MYSQL

spring.h2.console.enabled=true

 

 

Application 파일을 열고, '현재 파일' 에서 프로젝트 ▷  Run 한다.
크롬 브라우저 주소창에  localhost:8080/h2-console 을 입력한다.