쌓고 쌓다

[스프링 부트] 다중(멀티) 게시판으로 변경 - 23 본문

프로그래밍/spring

[스프링 부트] 다중(멀티) 게시판으로 변경 - 23

승민아 2023. 8. 14. 18:49

다중 게시판을 만드는 방법으로 두가지가 가능할 것 같다.

  1.  하나의 테이블로 게시판 구분 컬럼 추가
  2.  게시판 유형별로 테이블 생성

다음에 테이블을 나눠보기로하고...

현재 게시판의 유형별로 컬럼이 다르지 않아 한 테이블에서 구분 컬럼으로 구분하게 만들어 봤다.

 

게시글 테이블 category 컬럼 추가

alter table poster add category VARCHAR(255);

 

Category Enum

// 추후에 @Convert로 리팩토링해보자.
public enum Category {
    QUESTION, // 질문
    FREE
}

String으로 게시판 유형을 구분하는것보다 자바 Enum 타입으로 구분해보자.

Enum을 사용함으로써 값을 정해둠으로써 오타 문제를 해결할 수 있고 가독성도 좋고 값의 제한을 둘 수 있다.

 

Poster

@Entity
@Getter
@Setter
public class Poster {
    @Enumerated(EnumType.STRING)
    private Category category;
}

@Enumberated로 Enum 타입을 엔티티에 매핑할 수 있다.

EnumType.ORDIANL의 경우 순서 0, 1, 2 가 저장되지만

EnumType.STRING은 값 문자열 그 자체가 DB에 저장된다.

 

PosterRepository

public interface SpringDataJpaPosterRepository extends JpaRepository<Poster, Long> {
    Page<Poster> findByCategoryAndTitleContaining(Category category, String title, Pageable pageable);
    Page<Poster> findByCategory(Category category, Pageable pageable);
}

이제 게시글마다 카테고리 컬럼으로 분류할 수 있기에

게시글 목록 조회시 카테고리를 통해 분류하여 결과를 받아온다.

 

+ 메서드명과 파라미터 순서에 주의하자!

Page<Poster> findByTitleContainingAndCategory(Category category, String title, Pageable pageable);

위와 같이 메서드명과 파라미터 순서가 일치하지 않으면 원하는대로 파라미터가 넘어가지 않을 것이다.

 

 

게시글 카테고리도 생겼겠다.

아직 REST API 대해 제대로 공부하지 않았지만 흉내내보게 리팩토링을 해보았다.

  • GET /posters/{category} : 해당 카테고리 게시글 조회
  • POST /posters/{category} : 해당 카테고리 게시글 작성
  • GET /posters/view/{id} : 해당 게시글 상세보기
  • GET /posters/{category}/write : 해당 카테고리 게시글 작성 폼 호출
  • 게시글 수정이나 삭제는 게시글 PK로만으로 이뤄지기에 따로 수정하지는 않았다.
  • 그 외 DELETE, PUT 매핑을 해보고싶어서 다음에 매핑하여 리팩토링해볼 것이다.

 

게시글 조회만 보자면

@GetMapping("/posters/{category}")
    public String list(@PathVariable("category") Category category, Model model,
                       @RequestParam(defaultValue = "0") int page,
                       @RequestParam(required = false, defaultValue = "regdate") String order,
                       @RequestParam(required = false) String searchTitle) {
        ...
        model.addAttribute("category", category);
        return "posters/posterList";
    }

@PathVariable로 Category를 매핑하여 파라미터를 받는다.

이 값을 Model로 넘겨

게시글 페이지 이동이나 최신순, 댓글순 정렬, 검색, 게시글 작성등 로직에 넘겨 해당 카테고리를 유지하도록 로직을 작성했다.

이렇게 Model로 Category를 넘겨주는 방식으로 게시글 수정이나 삭제시 카테고리를 유지하도록 만들었다.

 

타임리프로 변수와 문자열 구분하여 작성하는데 헤맸던 부분을 요약한다...

 

게시글 작성시 카테고리 처리

<form th:action="@{|/posters/${category}|}">

게시글 작성시 Model에 넣어둔 Category를 사용하였다.

해당 카테고리로 게시글을 POST를 할 수 있다.

게시글 작성 폼에서 카테고리를 변경할 수 있게 할 수도 있겠지만 현재는 게시글 작성하기 버튼을 누르는 시점에 카테고리를 정해두었다.

 

 

타임리프 게시글 작성 태그 처리

 <button type="button" class="btn btn-primary float-end" th:onclick="|location.href='@{|/posters/${category}/write|}'|">작성하기

링크 표현식의 경우 @{}로 작성하며 내부에 ||를 감싸 리터럴 대체 문법을 사용할 수 있다.

리터럴 대체 문법을 사용하여 문자열과 변수를 같이 사용할 수 있다.

문자열과 변수를 구분하기위해 @{} 밖에서도 리터럴 대체 문법을 사용하여 감싸줬다.

 

아래는 페이징 처리를 위한 버튼인데

<a class="page-link" th:href="@{/posters/{category}(category=${category}, page=${next}, order=${order}, searchTitle=${searchTitle})}">다음</a>

쿼리 파라미터를 넘겨주거나하는 

URL 표현식에 대한 방법은 아래 블로그에서 정리를 잘해놓았다.

https://jddng.tistory.com/231

 

중요한것은 문자열내 변수와 그 변수내에 또 문자열과 변수가 있다면

문자열과 변수를 구분하기위해 ||를 감싸고 그 내부에 또 변수를 사용하기위해 또 ||로 감싸는 과정이 필요하다는것이다.

 

구현 결과

Comments