[spring] 게시판 CRUD 만들기

2022. 12. 30. 10:09·Spring

게시판 CRUD 만들기

JPA

  • 반복적인 CRUD SQL을 처리해준다.
  • SQL이 아닌 객체중심의 개발이 가능하도록 해준다.
//의존성 등록
dependecies{
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}

CRUD작성

  • 게시물 Entity
  • 실제 DB의 테이블과 매칭될 클래스이며 보통 Entity클래스라 부름 , JPA를 사용하면 DB데이터에 작업할 경우 실제 데이터보다는 Entity클래스의 수정을 통해 작업한다.
@Getter //Entity클래스는 DB와 맞닿아있는 중요한 클래스이기때문에 Setter 절대 사용하지 않기
@NoArgsConstructor
@Entity
public class Posts extends BaseTimeEntity {
    @Id //해당 테이블의 PK필드
    @GeneratedValue(strategy = GenerationType.IDENTITY) //PK의 생성규칙 현재 auto_increment
    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;
    }
}

JPA 생성

  • Post클래스로 DB에 접근하게해줄 PostsRepository
  • JpaRepository<Entity클래스, PK타입>을 상속하면 기본적인 CRUD메서드 자동생성
@Repository
public interface PostsRepository extends JpaRepository<Posts, Long> {}

웹계층

 

Web Layer

  • 흔히 @Controller와 같은 뷰와 관련된 영역

Service Layer

@Service , @Transaction 을 사용

  • 트랜잭션을 처리하는 영역
  • 비즈니스 로직이 실행되는 영역보다는 도메인에서 각 객체들의 비지니스 로직을 실행시키고, 순서보장하는 , 조합하는 영역

Repository Layer

@Repository 사용

  • DB에 접근하는 영역(DAO의 역할이라 생각)

DTOs

  • 계층간의 데이터 교환 또는 뷰 템플릿에 데이터를 넘겨줄때 사용하는 객체
  • 실제 DB를 갖다 쓰기는 부담이 되기에 사용

Domain Model

  • 실제 비즈니스 로직이 실행되는 영역
  • @Entity가 사용된 영역 역시 도메인 모델이라고 이해하면 된다
  • 택시앱으로 따지면 탑습 , 요금 , 배차 등등 각각이 도메인 객체라 볼수 있다.

코드

Web Layer

IndexController

@RequiredArgsConstructor
@Controller
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";
    }

    @GetMapping("/posts/update/{id}")
    public String postsUpdate(@PathVariable Long id,Model model){
        PostsResponseDto dto = postsService.findById(id);
        model.addAttribute("post", dto);
        return "posts-update";
    }
}

PostsApiController

@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);
    }

    @DeleteMapping("/api/v1/posts/{id}")
    public Long delete(@PathVariable Long id){
        postsService.delete(id);
        return id;
    }
}

Service Layer

PostsService

@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);
    }

    @Transactional(readOnly = true)
    public List<PostsListResponseDto> findAllDesc(){
        return postsRepository.findAllDesc().stream()
                .map(PostsListResponseDto::new)
                .collect(Collectors.toList());
    }
    @Transactional
    public void delete(Long id){
        Posts posts = postsRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("해당 게시글이 없습니다. id=" + id));
        postsRepository.delete(posts);
    }
}

Dtos

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();
    }
}

PostsResponseDto

@Getter
public class PostsResponseDto {
    private Long id;
    private String title;
    private String content;
    private String author;
    public PostsResponseDto(Posts entity){
        this.id = entity.getId();
        this.title= entity.getTitle();
        this.content= entity.getContent();
        this.author = entity.getAuthor();
    }
}

PostsSaveRequestDto

@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()
                .author(author)
                .title(title)
                .content(content)
                .build();
    }
}

PostsUpdateRequestDto

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

참고 교재

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

728x90
저작자표시 (새창열림)

'Spring' 카테고리의 다른 글

[스프링 MVC 1편] - 서블릿  (0) 2023.01.02
[스프링 MVC 1편] - 웹 애플리케이션 이해  (1) 2022.12.31
JPA Auditing기능이란?  (0) 2022.12.29
스프링 핵심 원리[기본편] - 의존관계 자동 주입  (0) 2022.12.28
스프링 핵심 원리[기본편] - 컴포넌트 스캔  (0) 2022.12.27
'Spring' 카테고리의 다른 글
  • [스프링 MVC 1편] - 서블릿
  • [스프링 MVC 1편] - 웹 애플리케이션 이해
  • JPA Auditing기능이란?
  • 스프링 핵심 원리[기본편] - 의존관계 자동 주입
study ticket
study ticket
  • study ticket
    혼자하는 공부
    study ticket
  • 전체
    오늘
    어제
    • 개발 (77)
      • 오류 (1)
      • Spring (13)
      • Java (0)
      • Data structure (6)
      • Algorithm (49)
        • 백준 (17)
        • 프로그래머스 (2)
      • 문제풀면서 알게되는것들 끄적 (2)
      • 머신러닝 (4)
        • sklearn (3)
        • pandas (1)
      • 프로젝트 (0)
        • 핏두 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준1157
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
study ticket
[spring] 게시판 CRUD 만들기
상단으로

티스토리툴바