/ SPRING

검색기능 추가하기

스프링 목록

스프링 부트 목록




이번에 해야할것

  • 백엔드에 검색 기능 요구사항 구현하기
  • 프론트에 검색한 목록들 페이징 처리 해주기






백엔드


1. RepBoardMapper.xml 동적 SQL로 구현

  • 기존의 RepBoardMapper의 findAll을 수정 하여 기능 구현 가능
  • findCount 도 검색된 목록들 페이징을 위해 수정

<select id="findAll" resultType="RepBoard" parameterType="map">
SELECT *
FROM (SELECT rownum r, a.*
      FROM (SELECT level,
            repboard.board_no,
            repboard.parent_no,
            repboard.board_id "boardC.id",
            repboard.board_title,
            repboard.board_content,       
            repboard.board_viewcount,
            repboard.board_dt
            FROM repboard 
            <where>
  			  <if test="word != null">
    			board_title LIKE '%${word}%' OR board_content LIKE '%${word}%'
  			  </if>
			</where>
           START WITH parent_no = 0
           CONNECT BY  PRIOR board_no = parent_no 
           ORDER SIBLINGS  BY board_no DESC) a
       )
WHERE r BETWEEN START_ROW(#{currentPage},#{cntPerPage}) AND END_ROW(#{currentPage},#{cntPerPage})

</select> 

<!--findCount 도 수정해줘야함-->
<select id="findCount" resultType="int">
SELECT COUNT(*) FROM repboard
<where>
  <if test="word != null">
    board_title LIKE '%${word}%' OR board_content LIKE '%${word}%'
  </if>
</where>
</select>








2. RepBoardDAOOracle.java

  • findByWord() 구현
  • finCount() 구현 - 검색한 게시물도 페이징 기능이 필요하니깐
	@Override
	public List<RepBoard> findByWord(String word, int currentPage, int cntPerPage) throws FindException{
		SqlSession session = null;
		try {
			session = sqlSessionFactory.openSession();
			Map<String, Object> map = new HashMap<>();
			map.put("currentPage", currentPage);//1페이지검색
			map.put("cntPerPage",  cntPerPage); //페이지별 보여줄 목록수
			map.put("word", word);
			List<RepBoard> list = 
				session.selectList(
					"com.my.board.RepBoardMapper.findAll", map
				);
			if(list.size() == 0) {
				throw new FindException("검색어에 해당하는 게시글이 없습니다");
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new FindException(e.getMessage());
		}finally {
			if(session != null) {
				session.close();
			}
		}
	}



    	@Override
	public int findCount(String word) throws FindException {
		SqlSession session = null;
		try {
			session = sqlSessionFactory.openSession();
			return session.selectOne("com.my.board.RepBoardMapper.findCount", word);
		}catch(Exception e) {
			e.printStackTrace();
			throw new FindException(e.getMessage());
		}finally {
			if(session != null) {
				session.close();
			}
		}
	}
	





3. RepBoardService.java

  • 서비스에서 검색기능 실행할때, findCount 도 실행
	public PageDTO<RepBoard> findByWord(String word, int currentPage) throws FindException{
		String url = "/board/search/"+word;
		int totalCnt = dao.findCount(word);
		List<RepBoard> list = dao.findByWord(word, currentPage, PageDTO.CNT_PER_PAGE);
		PageDTO<RepBoard> pageDTO = new PageDTO<>(url, currentPage, totalCnt, list);
		
		return pageDTO;
	}





4. RepBoardController.java

  • search() 추가 예시로 아래처럼 구현하면됨
	@GetMapping(value= {"/search", "/search/{word}", "/search/{word}/{currentPage}"})
	public Object  search(@PathVariable Optional<String>  word, 
			              @PathVariable Optional<Integer> currentPage) {
		try {
			PageDTO<RepBoard> pageDTO;
			String w = "";
			if(word.isPresent()) {
				w = word.get();
			}else {
				return list(currentPage);
			}
			int cp = 1;
			if(currentPage.isPresent()) { //currentPage값이 있는 경우
				cp = currentPage.get();			
			}
			pageDTO = service.findByWord(w, cp);
			return pageDTO;			
		}catch(FindException e) {
			Map<String, Object> returnMap = new HashMap<>();
			returnMap.put("msg", e.getMessage());
			returnMap.put("status", 0);
			return returnMap;
		}
	}







프론트


1. borderlist.html

  • 기존 html 해당 내용 추가 (div class=”table” 위에 넣을 것)
    <div class="search">
        <div class="searchInput">
            <input type="search" name="word" placeholder="통합검색">
            <a href="#" class="searchBtn">검색</a>
        </div>
    </div>
    





2. boderlist.js

  • 기존 js에 해당 내용 추가
//--검색클릭 시작--
$("div.boardlist>div.search>div.searchInput>a").click(function () {
    var word = $("div.boardlist>div.search>div.searchInput>input[name=word]").val();
    var url = backContextPath + '/board/search';
    if (word.trim() != '') {
        url += '/' + word;
    }
    $.ajax({
        "method": "GET",
        "transformRequest": [
            null
        ],
        "transformResponse": [
            null
        ],
        "jsonpCallbackParam": "callback",
        "url": url,
        "headers": {
            "Accept": "application/json, text/plain, */*"
        },
        "timeout": {},
        success: function (jsonData) {
			showList(jsonData);
        }, error(jqXHR) {
            alert(jqXHR.status);
        }
    });
    return false;
});
//--검색 클릭 끝--

3.boderlist.css

  • 해당 내용 추가
div.boardlist>div.search {
    background: #f4f4f2;
    padding: 15px 20px;
    border-radius: 10px;
    position: relative;
    margin-bottom: 35px;
    height: 50px;
} 

div.boardlist>div.search div.searchInput {
    position: absolute;
    right: 20px;
    top: auto;
    width: 395px;
    border-radius: 5px;
}
div.boardlist>div.search div.searchInput input {
    width: 343px;
    height: 28px;
    line-height: 28px;
    border: 1px solid #ddd;
    border-radius: 3px;
    float: left;
}
div.boardlist>div.search div.searchInput a.searchBtn {
    width: 42px;
    height: 28px;
    line-height: 28px;
    background: #777777;
    font-size: 12px;
    font-weight: bold;
    color: #ffffff;
    display: block;
    float: right;
    text-align: center;
    text-decoration: none;
    border-radius: 3px;
}





제대로 검색기능 작동하는 지 테스트 해보기

  • 아무 검색어도 입력 안할시 모든게시물 불러오기
  • 페이징 기능 제대로 작동하는지
  • ajax 통신 제대로 되는지

스프링 목록

스프링 부트 목록