[Playground] Spring API 검색 적용(feat. LIKE)

Daeya·2일 전

Playground

목록 보기
4/7

API 엔드포인트에 쿼리스트링 붙이고 제목/내용 검색

GET /api/memos?keyword=테스트
GET /api/memos?status=ING&keyword=메모&page=1&size=5

status 필터, 페이지네이션 다음으로 keyword 조건을 추가했다.
패턴은 status 필터와 동일하고, XML 조건만 LIKE로 바뀐다.


1. DBeaver에서 쿼리 확인

SELECT ID      as 'id'
     , TITLE   as 'title'
     , CONTENT as 'content'
     , STATUS  as 'status'
  FROM MEMO
 WHERE DEL_YN = 'N'
   AND (TITLE LIKE '%테스트%'
    OR CONTENT LIKE '%테스트%')
 ORDER BY ID
 LIMIT 5 OFFSET 0;

%테스트% → 앞뒤에 뭐가 와도 '테스트'가 포함되면 매칭 (부분 일치)

status + keyword 함께 쓸 때:

SELECT ID, TITLE, CONTENT, STATUS
  FROM MEMO
 WHERE DEL_YN = 'N'
   AND STATUS = 'ING'
   AND (TITLE LIKE '%메모%'
     OR CONTENT LIKE '%메모%')
 ORDER BY ID
 LIMIT 5 OFFSET 0;

2. Mapper.xml에 MyBatis 조건 추가

기존 selectMemoList, selectMemoCount 둘 다 같은 조건 추가

<if test="keyword != null and keyword != ''">
    AND (TITLE LIKE CONCAT('%', #{keyword}, '%')
      OR CONTENT LIKE CONCAT('%', #{keyword}, '%'))
</if>

CONCAT('%', #{keyword}, '%') — SQL에 %를 직접 붙이지 않고 MyBatis에서 조합

목록·count 쿼리 WHERE 조건은 항상 동일하게 맞춘다


3. MemoVO에 검색용 필드 추가

private String keyword;
// getter / setter
  • DB 컬럼이 아니라 MyBatis에 넘기는 검색 조건
  • size, offset과 같은 역할

4. Service에 keyword param 추가

public MemoPageVO selectMemoPage(String status, String keyword, int page, int size) {
    MemoVO param = new MemoVO();
    param.setStatus(status);
    param.setKeyword(keyword);
    param.setSize(size);
    param.setOffset((page - 1) * size);

    int total = memoMapper.selectMemoCount(param);
    List<MemoVO> items = memoMapper.selectMemoList(param);
    // ... MemoPageVO 반환
}
  • 새 메서드 안 만듦 → 기존 selectMemoPagekeyword만 추가
  • Controller의 keywordparam.setKeyword()로 Mapper에 전달

5. Controller에 @RequestParam 추가

@GetMapping
public MemoPageVO list(
    @RequestParam(required = false) String status,
    @RequestParam(required = false) String keyword,
    @RequestParam(defaultValue = "1") int page,
    @RequestParam(defaultValue = "5") int size
) {
    return memoService.selectMemoPage(status, keyword, page, size);
}

6. Postman으로 확인

GET http://localhost:8080/playground/api/memos?keyword=테스트
GET http://localhost:8080/playground/api/memos?keyword=테스트&page=1&size=5
GET http://localhost:8080/playground/api/memos?status=ING&keyword=메모&page=1&size=5

응답 형태는 페이지네이션과 동일:

{
  "items": [ ... ],
  "total": 3,
  "page": 1,
  "size": 5
}

정리

기능

  • GET /api/memos?keyword=테스트 → 제목/내용에 '테스트' 포함된 메모만 반환
  • status 필터, 페이지네이션과 함께 사용 가능

흐름 (요청 → DB)

Controller: @RequestParam keyword
→ Service: param.setKeyword(keyword)
→ Mapper: selectMemoList(param) / selectMemoCount(param)
→ XML: keyword 있으면 TITLE LIKE ... OR CONTENT LIKE ...
→ DB

만든 순서 (DB → 요청)

  1. DBeaver: LIKE '%키워드%'
  2. Mapper.xml: <if test="keyword"> + LIKE (목록·count 둘 다)
  3. MemoVO: keyword
  4. Service: param.setKeyword(keyword)
  5. Controller: @RequestParam(required = false) String keyword
  6. Postman: GET .../api/memos?keyword=테스트

패턴 (다른 조건 추가할 때도 동일)

@RequestParam 추가
  → Service param.setXxx()
  → XML <if test="xxx">
  → Postman 확인

참고

profile
Daeya

0개의 댓글