자유게시판에서 Mybatis 동적쿼리를 활용해 검색하기 기능을 구현하려 한다.
[요약]
- 검색할 수 있는 방법은 2가지다. 그 2가지가 동작할 수 있도록 구현한다. (script 구현)
* 검색란에 검색 키워드를 입력한 후 엔터키를 눌러 검색
* 검색란에 검색 키워드를 입력한 후 돋보기 모양을 눌러 검색
[free-list.jsp 수정 ① - form 형태 수정]
// form : search-from
// 검색기능 구현 시(submit 시) form 안에 포함되어 있는 input과 select(name) 값이 전송된다.
// action : /board/free-list.do 로 정보 전달
// method : post 방식
<form id="search-form" action="/board/free-list.do" method="post">
<input type="hidden" name="pageNum" value="${page.cri.pageNum}">
<input type="hidden" name="amount" value="${page.cri.amount}">
<div class="row">
<div class="col-3">
// name : searchCondition (전체, 제목, 내용, 작성자 중 선택)
<select class="form-select" name="searchCondition">
<option value="all"
<c:if test="${searchMap == null || searchCondition == 'all'}">
selected
</c:if>>전체</option>
<option value="title"
<c:if test="${searchCondition == 'title'}">
selected
</c:if>>제목</option>
<option value="content"
<c:if test="${searchCondition == 'content'}">
selected
</c:if>>내용</option>
<option value="writer"
<c:if test="${searchCondition == 'writer'}">
selected
</c:if>>작성자</option>
</select>
</div>
<div class="col-9">
<div class="row">
<div class="col-11">
// name : searchKeyword (검색창)
<input type="text" class="form-control w-100" name="searchKeyword" value="${searchKeyword}">
</div>
<div class="col-1 d-flex align-items-center">
// search-icon : 돋보기 모양
<i class="bi bi-search" id="search-icon"></i>
// button : 검색버튼
<button type="submit" id="btnSearch">검색</button>
</div>
</div>
</div>
[free-list.jsp 수정 ② - 검색기능 구현]
<script>
$(() => {
// 1. 돋보기 모양을 눌렀을 때
$("#search-icon").on("click", (e) => {
// 페이지 번호가 1번으로 가게 설정
// 그 이유는 페이지 번호를 2번 이후부터는 검색하게 되면
// 검색정보가 나오지 않게 된다.
$("input[name='pageNum']").val(1);
// form을 전송하게 된다.
$("#search-form").submit();
});
// 2. 키워드 검색 후 enter를 눌렀을 때
// 검색창에다 enter 클릭 시
$("input[name='searchKeyword']").on("keypress", (e) => {
if(e.key === 'Enter') {
// 엔터 클릭 시 페이지 번호가 1번으로 가게 설정
$("input[name='pageNum']").val(1);
}
});
</script>
[controller 수정]
@RequestMapping("/free-list.do")
public String freeListView(Model model, @RequestParam Map<String, String> searchMap) {
boardService = applicationContext.getBean("freeBoardServiceImpl", BoardService.class);
// searchMap을 매개변수로 받는 객체를
// freeBoardList라는 이름을 키로 갖도록
// Map에 추가
model.addAttribute("freeBoardList", boardService.getBoardList(searchMap);
return "board/free-list";
}
- Map 형태로 searchMap 을 매개변수로 받아 freeboardlist 라는 이름으로 키 값이 되는 객체를 모델에 포함
* 위의 free-list에서 searchMap 에 포함되는 내용은 아래와 같다.
{
"pageNum": "현재 페이지 번호",
"amount": "한 페이지에 표시할 게시글 수",
"searchCondition": "사용자가 선택한 검색 조건", // 예: "all", "title", "content", "writer"
"searchKeyword": "사용자가 입력한 검색 키워드"
}
- 기존에 free-list.do는 getMapping 이였으나, post 기능도 구현해야 하기 때문에 @RequestMapping으로 변환
[service 수정]
List<BoardDto> getBoardList(Map<String, String> searchMap);
[Impl 수정]
@Override
public List<BoardDto> getBoardList(Map<String, String> searchMap) {
Map<String, Object> searchMap = new HashMap<>();
searchMap.put("search", searchMap);
return freeBoardDao.getBoardList(searchMap);
}
[dao 수정 ]
public List<BoardDto> getBoardList(Map<String, Object> searchMap) {
List<BoardDto> boardDtoList = new ArrayList<>();
boardDtoList = mybatis.selectList("FreeBoardDao.getBoardList", searchMap);
return boardDtoList;
}
[mapper - Mybatis 동적쿼리 사용]
<select id="getBoardList" parameterType="map" resultType="board">
SELECT F.ID
, F.TITLE
, F.CONTENT
, F.WRITER_ID
, M.NICKNAME
, F.REGDATE
, F.MODDATE
, F.CNT
FROM FREEBOARD F
JOIN MEMBER M
ON F.WRITER_ID = M.ID
-- mybatis의 동적 쿼리 사용
// 어떠한 경우든
WHERE 1=1
// 키워드가 null 값이 아니고 공란이 아닐 때
<if test="search.searchKeyword != null and search.searchKeyword != ''">
// 1. search Map에서 searchCondition(선택) 값이 전체인 경우
<if test="search.searchCondition == 'all'">
// 제목이 search Map에서 searchKeyword(검색어) 인 경우
AND (F.TITLE LIKE CONCAT('%', #{search.searchKeyword}, '%')
// 내용이 search Map에서 searchKeyword(검색어) 인 경우
OR F.CONTENT LIKE CONCAT('%', #{search.searchKeyword}, '%')
// 작성자가 search Map에서 searchKeyword(검색어) 인 경우
OR M.NICKNAME LIKE CONCAT('%', #{search.searchKeyword}, '%'))
</if>
// 2. search Map에서 searchCondition(선택) 값이 제목인 경우
<if test="search.searchCondition == 'title'">
AND F.TITLE LIKE CONCAT('%', #{search.searchKeyword}, '%')
</if>
// 3. search Map에서 searchCondition(선택) 값이 내용인 경우
<if test="search.searchCondition == 'content'">
AND F.CONTENT LIKE CONCAT('%', #{search.searchKeyword}, '%')
</if>
// 4. search Map에서 searchCondition(선택) 값이 작성자인 경우
<if test="search.searchCondition == 'writer'">
AND M.NICKNAME LIKE CONCAT('%', #{search.searchKeyword}, '%')
</if>
</if>
LIMIT #{cri.amount} OFFSET #{cri.startNum}
</select>
[결과]
[문제점] 근데 검색 후 검색한 내용이 사라지게 된다. 이를 해결하기 위해서는?
[boardController 수정]
- Model에 다양한 형태의 객체를 넣을 수 있다.
-
@RequestMapping("/free-list.do")
public String freeListView(Model model, @RequestParam Map<String, String> searchMap) {
boardService = applicationContext.getBean("freeBoardServiceImpl", BoardService.class);
model.addAttribute("freeBoardList", boardService.getBoardList(searchMap));
model.addAttribute("searchMap", searchMap);
return "board/free-list";
}
[free-list.jsp 수정]
- controller에서 Map에 넣은 searchMap을 .jsp 에 표현(searchMap.searchCondion, searchMap.searchKeyword)
// form : search-from
// 검색기능 구현 시(submit 시) form 안에 포함되어 있는 input과 select(name) 값이 전송된다.
// action : /board/free-list.do 로 정보 전달
// method : post 방식
<form id="search-form" action="/board/free-list.do" method="post">
<input type="hidden" name="pageNum" value="${page.cri.pageNum}">
<input type="hidden" name="amount" value="${page.cri.amount}">
<div class="row">
<div class="col-3">
// name : searchCondition (전체, 제목, 내용, 작성자 중 선택)
<select class="form-select" name="searchCondition">
<option value="all"
<c:if test="${searchMap == null || searchMap.searchCondition == 'all'}">
selected
</c:if>>전체</option>
<option value="title"
<c:if test="${searchMap.searchCondition == 'title'}">
selected
</c:if>>제목</option>
<option value="content"
<c:if test="${searchMap.searchCondition == 'content'}">
selected
</c:if>>내용</option>
<option value="writer"
<c:if test="${searchMap.searchCondition == 'writer'}">
selected
</c:if>>작성자</option>
</select>
</div>
<div class="col-9">
<div class="row">
<div class="col-11">
// name : searchKeyword (검색창)
<input type="text" class="form-control w-100" name="searchKeyword" value="${searchMap.searchKeyword}">
</div>
<div class="col-1 d-flex align-items-center">
// search-icon : 돋보기 모양
<i class="bi bi-search" id="search-icon"></i>
// button : 검색버튼
<button type="submit" id="btnSearch">검색</button>
</div>
</div>
</div>
'백엔드 > Spring Framework' 카테고리의 다른 글
게시판 구현 / 6. 페이징(게시글 총 개수 설정) (0) | 2024.07.20 |
---|---|
게시판 구현 / 6. 페이징 (0) | 2024.07.20 |
게시판 구현 / 4. 게시판 디테일(글 수정, 삭제) (0) | 2024.07.17 |
게시판 구현 / 3. 게시판 글 등록 및 카테고리 (0) | 2024.07.17 |
게시판 구현 / 2. 로그인 (0) | 2024.07.16 |