웹개발/SpringBoot

SpringBoot 검색기능+Enum활용

bergerac 2025. 5. 31. 09:11

https://github.com/seoyoonchoi/Korea_sleep_Tech_springBoot/tree/main/src/main/java/com/example/korea_sleepTech_springboot

 

Korea_sleep_Tech_springBoot/src/main/java/com/example/korea_sleepTech_springboot at main · seoyoonchoi/Korea_sleep_Tech_springB

Contribute to seoyoonchoi/Korea_sleep_Tech_springBoot development by creating an account on GitHub.

github.com

실제 코드를 더 확인하고 싶다면 위 링크를 통해서 확인할 수 있다.

 

📁 프로젝트 구조

korea_sleepTech_springboot/
├── common/
│   └── ApiMappingPattern.java
├── controller/
│   └── BookController.java
├── dto/
│   ├── request/
│   │   ├── BookCreateRequestDto.java
│   │   └── BookUpdateRequestDto.java
│   └── response/
│       └── BookResponseDto.java
├── entity/
│   ├── C_Book.java
│   └── C_Category.java
├── repository/
│   └── BookRepository.java
├── service/
│   └── BookService.java

Entity 구성 - C_Book & C_Category

@Entity
@Table(name = "book")
public class C_Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, length = 50)
    private String writer;

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

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

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private C_Category category;
}

 

public enum C_Category {
    NOVEL, ESSAY, POEM, MAGAZINE
}

 

ENUM 사용 이유

  • 고정된 선택지를 코드 수준에서 제한 가능 (컴파일 타임에서 오류 감지)
  • DB에 저장될 땐 VARCHAR, Java 코드에선 타입 안정성 보장
  • 프리미티브 String 필드로 처리할 경우 오타나 정합성 오류 위험이 높음 → ENUM은 이를 예방

DTO 계층 - 요청과 응답 분리

public class BookCreateRequestDto {
    private String writer;
    private String title;
    private String content;
    private C_Category category;
}

 

DTO를 통해 외부 요청에 대한 유효성 처리, 내부 도메인 객체와의 결합 최소화, 역직렬화/직렬화의 명확한 경계 설정이 가능하다.

  • CreateRequestDto: 클라이언트가 책을 등록할 때 사용하는 요청 데이터
  • UpdateRequestDto: 책 수정 시 사용. 전체 데이터가 아닌 수정 가능한 항목만 분리
  • ResponseDto: 클라이언트에게 반환할 데이터. 민감하거나 불필요한 정보는 제외

Service 계층 - 핵심 비즈니스 로직

public ResponseDto<BookResponseDto> createBook(BookCreateRequestDto requestDto) {
    C_Book newBook = new C_Book(null, ..., ...);
    ...
    return ResponseDto.setSuccess("책 등록 완료", bookDto);
}

중요한 설계 포인트

  • C_Book 객체 생성 시 null ID → JPA가 자동으로 ID 부여
  • DTO → Entity → Repository.save() → Entity → DTO → Response 구조
  • Service 계층에서는 Controller와 Repository의 중간 다리 역할을 하며, 핵심 도메인 처리 로직을 담당

검색 기능 예시

public ResponseDto<List<BookResponseDto>> getBooksByTitleContaining(String keyword) {
    List<C_Book> result = bookRepository.findByTitleContaining(keyword);
    ...
}

 

  • findByTitleContaining: Spring Data JPA가 제공하는 메서드 이름 기반 쿼리 생성 기능
  • Stream + map(): Entity 리스트 → ResponseDto 리스트 변환

Controller - RESTful API 설계

@RequestMapping("/api/v1/user/books")
@RestController
public class BookController {
    ...
}

 

HTTP Method 매핑 구조

  • POST /books: 책 등록
  • GET /books: 전체 책 목록 조회
  • GET /books/{id}: 단일 책 조회
  • PUT /books/{id}: 책 내용 + 카테고리 수정
  • DELETE /books/{id}: 책 삭제

🔍 검색 API

  • GET /books/search/title?keyword=키워드
  • GET /books/category/{category}
  • GET /books/search/category-writer?writer=xxx&category=yyy

@RequestParam vs @PathVariable 구분의 기준

 

유형 목적 예시
@PathVariable 고정된 리소스를 식별 /category/NOVEL
@RequestParam 필터링/검색 조건 /search/title?keyword=자바