[SB] 18. Search 검색

최재원's avatar
May 08, 2025
[SB] 18. Search 검색
Contents
Search
DB에서 조회 시 like 연산자를 사용해 keyword가 포함된 데이터를 가져오면 된다

Search

notion image

board/list

{{> layout/header}} <div class="container p-5"> <div class="mb-3 d-flex justify-content-end"> <form action="/" class="d-flex"> <input class="form-control me-2" type="text" placeholder="검색..." name="keyword"> <button class="btn btn-primary flex-shrink-0" type="submit">검색</button> </form> </div> {{#model.boards}} <div class="card mb-3"> <div class="card-body"> <div class="d-flex justify-content-between"> <h4 class="card-title mb-3">{{title}}</h4> {{^isPublic}} <div> <span class="badge bg-secondary">비공개</span> </div> {{/isPublic}} </div> <a href="/board/{{id}}" class="btn btn-primary">상세보기</a> </div> </div> {{/model.boards}} <ul class="pagination d-flex justify-content-center"> <li class="page-item {{#model.isFirst}}disabled{{/model.isFirst}}"> <a class="page-link" href="?page={{model.prev}}&keyword={{model.keyword}}">Previous</a> </li> {{#model.numbers}} <li class="page-item"><a class="page-link" href="?page={{.}}&keyword={{model.keyword}}">{{.}}</a></li> {{/model.numbers}} <li class="page-item {{#model.isLast}}disabled{{/model.isLast}}"> <a class="page-link" href="?page={{model.next}}&keyword={{model.keyword}}">Next</a> </li> </ul> </div> {{> layout/footer}}
  • 빨간줄 → input의 값을 어느 key값으로 받을지 결정

BoardController

@GetMapping("/") public String list(HttpServletRequest request, @RequestParam(required = false, value = "page", defaultValue = "0") Integer page, @RequestParam(required = false, value = "keyword", defaultValue = "") String keyword) { User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) { request.setAttribute("model", boardService.목록보기(null, page, keyword)); } else { request.setAttribute("model", boardService.목록보기(sessionUser.getId(), page, keyword)); } return "board/list"; }
  • required = false → null을 허용하겠다
    • /?keyword= → 이렇게 오면 공백
    • / → 이렇게 오면 null 이다
  • defaultValue = "" → null 이 들어올때 기본값으로 공백을 설정

BoardService

public BoardResponse.DTO 목록보기(Integer userId, Integer page, String keyword) { if (userId == null) { // return boardRepository.findAll(page); List<Board> boards = boardRepository.findAll(page, keyword); Long totalCount = boardRepository.totalCount(keyword); return new BoardResponse.DTO(boards, page, totalCount.intValue(), keyword); } else { // return boardRepository.findAll(userId, page); List<Board> boards = boardRepository.findAll(userId, page, keyword); Long totalCount = boardRepository.totalCount(userId, keyword); return new BoardResponse.DTO(boards, page, totalCount.intValue(), keyword); } }
  • Controller에서 받은 keword를 전달한다

BoardResponse

@Data public static class DTO { private List<Board> boards; private Integer current; private Integer next; private Integer prev; private Integer totalCount; private Integer size; private Integer totalPages; private Boolean isFirst; // currentPage를 알아야 한다 private Boolean isLast; // totalCount, size=3, totalPage를 알아야 한다 private List<Integer> numbers; private Integer pageSize; private String keyword; // null 이면 머스테치에서 터진다 public DTO(List<Board> boards, Integer current, Integer totalCount, String keyword) { this.boards = boards; this.next = current + 1; this.prev = current - 1; this.current = current; this.totalCount = totalCount; this.size = 3; this.totalPages = makeTotalPages(totalCount, this.size); this.isFirst = current == 0; this.isLast = current == this.totalPages - 1; this.numbers = makeNumbers(current, this.totalPages); this.keyword = keyword; }
  • Controller에서 받은 keword를 전달한다

BoardRepository

// locahost:8080?page=0 public List<Board> findAll(int page, String keyword) { String sql; if (keyword.isBlank()) { sql = "select b from Board b where b.isPublic = true order by b.id desc"; } else { sql = "select b from Board b where b.isPublic = true and b.title like :keyword order by b.id desc"; } Query query = em.createQuery(sql, Board.class); if (!keyword.isBlank()) query.setParameter("keyword", "%" + keyword + "%"); query.setFirstResult(page * 3); query.setMaxResults(3); return query.getResultList(); } public List<Board> findAll(Integer userId, int page, String keyword) { String sql; if (keyword.isBlank()) { sql = "select b from Board b where b.isPublic = true or b.user.id = :userId order by b.id desc"; } else { sql = "select b from Board b where b.isPublic = true or b.user.id = :userId and b.title like :keyword order by b.id desc"; } Query query = em.createQuery(sql, Board.class); query.setParameter("userId", userId); if (!keyword.isBlank()) query.setParameter("keyword", "%" + keyword + "%"); query.setFirstResult(page * 3); query.setMaxResults(3); return query.getResultList(); } public Long totalCount(String keyword) { String sql; if (!(keyword.isBlank())) { sql = "select count(b) from Board b where b.isPublic = true and b.title like :keyword"; } else { sql = "select count(b) from Board b where b.isPublic = true"; } Query query = em.createQuery(sql, Long.class); // keyword를 포함 : title like %keyword% if (!(keyword.isBlank())) query.setParameter("keyword", "%" + keyword + "%"); return (Long) query.getSingleResult(); } public Long totalCount(int userId, String keyword) { String sql; if (!(keyword.isBlank())) { sql = "select count(b) from Board b where b.isPublic = true or b.user.id = :userId and b.title like :keyword"; } else { sql = "select count(b) from Board b where b.isPublic = true or b.user.id = :userId"; } Query query = em.createQuery(sql, Long.class); // keyword를 포함 : title like %keyword% if (!(keyword.isBlank())) query.setParameter("keyword", "%" + keyword + "%"); query.setParameter("userId", userId); return (Long) query.getSingleResult(); }
 
Share article

jjack1