Contents
SearchDB에서 조회 시 like 연산자를 사용해 keyword가 포함된 데이터를 가져오면 된다
Search

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