[스프링] 검색어 자동 완성

손성우·2021년 11월 1일
1

스프링

목록 보기
3/9

1. JS

프론트에서는 검색어 입력시 DB에서 해당 검색어를 포함하는 글제목 또는 글쓴이를 불러올 것이다.

<%-- 글검색 폼 --%>
	<form name="searchFrm" style="margin-top: 20px;">
		<select name="searchType" id="searchType">
			<option value="subject">제목</option>
			<option value="name">글쓴이</option>
		</select>
		<input type="text" id="searchWord" name="searchWord" size="100" autocomplete="off">
		<input type="hidden" style="display: none;">
		<button type="button" class="btn btn-secondary btn-sm" onclick="goSearch()">검색</button>
	</form>
	<%-- 검색어 자동완성이 보여질 구역 --%>
	<div id="displayList" style="border: solid 1px gray; height: 100px; overflow: auto; margin-left: 77px; margin-top; -1px; border-top: 0px;">
	</div>
    
<script>
$("#displayList").hide();
// 검색어의 길이가 바뀔 때마다 호출
var wordLength = $(this).val().trim().length;
if(wordLength == 0){
			$("#displayList").hide();
		} else {
			$.ajax({
				url:"/wordSearchShow.action",
				type:"get",
				data:{"searchType": $("#searchType").val(),
					  "searchWord": $("#searchWord").val() },
				dataType:"json",
				success:function(json){
					if(json.length > 0){
						// 검색된 데이터가 있는 경우
						var html = "";
						$.each(json, function(index, item){
							var word = item.word;
                            // 검색목록들과 검색단어를 모두 소문자로 바꾼 후 검색단어가 나타난 곳의 index를 표시.
							var index = word.toLowerCase().indexOf( $("#searchWord").val().toLowerCase() );
							// jaVa -> java
							var len = $("#searchWord").val().length;
							// 검색한 단어를 파랑색으로 표현
							var result = word.substr(0, index) + "<span style='color:blue;'>"+word.substr(index, len)+"</span>" + word.substr(index+len);
							html += "<span class='result' style='cursor:pointer;'>" + result + "</span><br>";
						});
						
						var input_width = $("#searchWord").css("width"); // 검색어 input 태그 width 알아오기
						$("#displayList").css({"width":input_width}); // 검색 결과의 width와 일치시키기
						$("#displayList").html(html);
						$("#displayList").show();
					}
					
				},
				error: function(request, status, error){
	                alert("code: "+request.status+"\n"+"message: "+request.responseText+"\n"+"error: "+error);
	            }
				
			});

		}
        
        // 자동완성 목록을 클릭하면 검색하기
	$(document).on('click', ".result", function(){
		var word = $(this).text();
		$("#searchWord").val(word);
		goSearch(); // 검색기능
	});
</script>

2. 자바

@ResponseBody
	@RequestMapping(value="/wordSearchShow.action", method=RequestMethod.GET, produces="text/plain;charset=UTF-8")
	public String wordSearchShow(HttpServletRequest request) {
				
		String searchType = request.getParameter("searchType");
		String searchWord = request.getParameter("searchWord");
		
		Map<String, String> paraMap = new HashMap<>();
		paraMap.put("searchType", searchType);
		paraMap.put("searchWord", searchWord);
		
		List<String> wordList = boardService.wordSearchSHow(paraMap);
		JSONArray jsonArr = new JSONArray(); 
			if(wordList != null) {
				for(String word : wordList) {
					JSONObject jsonObj = new JSONObject();
					jsonObj.put("word", word);			
					jsonArr.put(jsonObj);
				}
			}
		return jsonArr.toString();
	}
  1. Mybatis
    지금은 간단하게 글자순으로 나열을 했다. 나중에는 검색어 랭킹순으로 나열해보겠다. 이름은 중복되면 안되기에 distinct로 먼저 감싸주고 rownum으로 5개만 출력되게끔 하였다.
    유지보수를 위해 그 외 나머지 중복제거가 필요 없는 것들은 otherwise로 처리되게끔 했다.
<select id="wordSearchSHow" parameterType="HashMap" resultType="String">
    		      
	      <choose>
    		<when test="searchType eq 'name'">
    			select name
    			from(
    			select rownum as rnum, name
				from(
					select distinct name
					from tbl_board
					where status = 1
					and name like '%'|| lower(#{searchWord}) ||'%'
				)
				where rownum &lt; 6
				)
    		</when>
    		<otherwise>
    			select ${searchType} 
				from(
					select ROWNUM as rnum, ${searchType}
					from tbl_board
					where status = 1
					and lower( ${searchType} ) like '%'|| lower(#{searchWord}) ||'%'
				)
				where rownum &lt; 6
    		</otherwise>
    	</choose>   
    </select>
profile
백엔드 개발자를 꿈꾸며 공부한 내용을 기록하고 있습니다.

2개의 댓글

comment-user-thumbnail
2022년 7월 23일

안녕하세요. 혹시 전체 소스 없는지 궁금합니다.

답글 달기
comment-user-thumbnail
2024년 9월 27일

Controller, Service, Dao 부분 코드 알 수 있을까요??

답글 달기