본문 바로가기

programming/Gukbi

국비 교육 91일차 - 검색 기능 완성

728x90
반응형

프로젝트 발표가 얼마남지 않아서 이번주에는 프로젝트와 관련한 기능을 수업시간에 구현해주고 계신다.

 

그 중에서 내가 맡은 검색 기능을 다시 구현해주셔서 만들어봤다. 수업시간에 예제로 해봤지만 포스팅은 프로젝트 내용으로 해보겠다. 

 

일단 검색기능을 구현할 css를 만들어 준다. 

 

 <div class="filter-bar d-flex flex-wrap align-items-center">
           <div class="sorting">
              <select id="findTitle" class="input-sm">
                <option value="T">책 제목</option>
                <option value="A">저자</option>
                <option value="TA">책 제목+저자</option>
              </select> 
            </div>
            <div>
              <div class="input-group filter-bar-search">
                <input type="text" placeholder="Search" id="keyword" autocomplete=off>
                <input type="hidden" id="page" value="${curpage }">
                <input type="hidden" id="cno" value="${curcno}">
                <div class="input-group-append">
                  <button type="button" id="findBtn"><i class="ti-search"></i></button>
                </div>
              </div>
            </div>
          </div>

 일단 이렇게 만들어 줬다. 어떤 검색어로 찾을건지 select id를 지정을 해주고, 검색어를 받아와서 역시 keyword로 받아준다. 위의 코드에서는 현재 cno, page를 받아왔지만 일단 생략하고 가겠다. 

 

이렇게 만들어 줬으면 VO를 만들어준다. 

 

private String findTitle;
	private String userFind;
	public String getFindTitle() {
		return findTitle;
	}
	public void setFindTitle(String findTitle) {
		this.findTitle = findTitle;
	}
	public String getUserFind() {
		return userFind;
	}
	public void setUserFind(String userFind) {
		this.userFind = userFind;
	}
	
	public String[] getFuArr()
	{
		return findTitle==null?new String[]{}:findTitle.split("");
	}

 각각 vo를 만들어 주되, getFuArr이라는 문자열 변수를 하나 더 만들어 준다. 저장했던 findTitle의 글자를 하나하나씩 잘라서 가져오기 위함이다. 

 

그리고 mapper 에서 sql문장을 써준다

 

<!-- 관련 새책 리스트 -->
<select id="findNewBookList" resultType="BookVO" parameterType="String">
SELECT no, cno, title, poster, price FROM BOOK
WHERE title LIKE '%'||#{title}||'%'
</select>
<select id="booksFindData" resultType="BooksVO" parameterType="hashmap">
SELECT no, title, author, poster, category, price, sale_price 
FROM book_s
WHERE 
<trim prefix="(" suffix=")" prefixOverrides="OR">
<foreach collection="FuArr" item="findTitle">
<trim prefix="OR">
<choose>
 <when test="findTitle=='T'.toString()">
 title LIKE '%'||#{keyword}||'%'
 </when>
  <when test="findTitle=='A'.toString()">
 author LIKE '%'||#{keyword}||'%'
 </when>
</choose>
</trim>
</foreach>
</trim>
</select>

 FuArr에서 잘라준 알파벳대로 나눠서 처리를 해준다. 매개변수는 FuArr, 검색어 두개를 받아와야하기 때문에 map으로 처리를 해준다. 

 

그리고 jsp로 넘겨줄때 ajax로 화면을 처리해줄거라 RestController를 사용해준다. 

 

package com.sist.web;

import java.util.*;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sist.dao.BooksDAO;
import com.sist.vo.BooksFindVO;
import com.sist.vo.BooksVO;

@RestController
public class BooksRestController {
	@Autowired
	private BooksDAO dao;
	
	@PostMapping("junggo/junggo_find.do")
	public String junggo_find(BooksFindVO vo)
	{
		System.out.println(vo.getFindTitle());
		System.out.println(vo.getUserFind());
		Map map=new HashMap();
		map.put("keyword", vo.getUserFind());
		map.put("FuArr", vo.getFuArr());
		
		List<BooksVO> fList=dao.booksFindData(map);
		JSONArray arr=new JSONArray();
		for(BooksVO fvo:fList)
		{
			// no, title, author, poster, category 
			JSONObject obj=new JSONObject();
			obj.put("no", fvo.getNo());
			obj.put("title", fvo.getTitle());
			obj.put("author", fvo.getAuthor());
			obj.put("poster", fvo.getPoster());
			obj.put("category", fvo.getCategory());
			obj.put("price", fvo.getPrice());
			obj.put("sale_price", fvo.getSale_price());
			arr.add(obj);
		}
		return arr.toJSONString();
	}
}

 junggo_find.do를 받으면 일단 매개변수 FindVO를 받아온다. 

일단 map에 UserFind, FuArr 값을 채워 넣어준다. FuArr은 사용자가 select에서 option을 선택하기만 하면 자동으로 채워진다. 

 

이걸 mapper에서 사용한 변수로 key값을 채워서 넘겨준다. 이때 꼭 key명과 mapper의 변수명이 일치해야한다. 

 

map.put("keyword", vo.getUserFind());
map.put("FuArr", vo.getFuArr());
<foreach collection="FuArr" item="findTitle">
<when test="findTitle=='T'.toString()">
 title LIKE '%'||#{keyword}||'%'
 </when>

위와 아래를 비교해보면 변수명을 제대로 맞춰준 것을 확인 할 수 있다. 

 

map에 값을 채워주고 난 후 이걸 메소드에 매개변수로 대입해줘서 list 데이터를 저장해준다. 

List<BooksVO> fList=dao.booksFindData(map);

그리고 값을 넘겨주기 위해 JSONArray를 만들어 준다. JSON에서 Array는 자바에서 List에 해당한다고 생각하면 된다. 

JSONArray arr=new JSONArray();
		for(BooksVO fvo:fList)
		{
			// no, title, author, poster, category 
			JSONObject obj=new JSONObject();
			obj.put("no", fvo.getNo());
			obj.put("title", fvo.getTitle());
			obj.put("author", fvo.getAuthor());
			obj.put("poster", fvo.getPoster());
			obj.put("category", fvo.getCategory());
			obj.put("price", fvo.getPrice());
			obj.put("sale_price", fvo.getSale_price());
			arr.add(obj);
		}
		return arr.toJSONString();

 그러고 나서 for문을 이용하여 각각의 JSONObject에 세부 사항을 채워 넣어준다. JSONObject는 자바에서 VO에 해당한다고 생각하면 된다. 

 

이렇게 JSONArray에 값을 다 추가해준 뒤, arr을 문자열로 변환해서 넘겨준다. 

 

그러면 이 값을 ajax에서 처리해서 화면에 출력해주면 끝난다. 

<script type="text/javascript">
 $(function(){
	$('#keyword').keyup(function(){
		$('#bookList > div').hide();
	})
	$('#findBtn').click(function(){
		let userFind=$('#keyword').val();
		let findTitle=$('#findTitle').val();
		if(userFind.trim()=="")
		{
			$('#keyword').focus();
			return;
		}
		$.ajax({
			type:'post',
			url:'junggo_find.do',
			data:{"userFind":userFind, "findTitle":findTitle},
			success:function(result)
			{
				let json=JSON.parse(result);
				let jsonData='';
				for(let i=0; i<json.length; i++)
				{
					jsonData+='<div class="col-md-6 col-lg-4">'
		                +'<div class="card text-center card-product">' 
	                  +'<div class="card-product__img">'
	                   +'<img class="card-img" src="'+json[i].poster+'">'
	                    +'<ul class="card-product__imgOverlay">'
	                      +'<li><button><i class="ti-search"></i></button></li>'
	                      +'<li><button><i class="ti-shopping-cart"></i></button></li>'
	                      +'<li><button><i class="ti-heart"></i></button></li>'
	                    +'</ul>'
	                  +'</div>'
	                 
	                  +'<div class="card-body">'
	                    +'<p>'+json[i].category+'</p>'
	                    +'<h4 class="card-product__title">'+json[i].title+'</h4>'
	                    +'<p id="price">'+json[i].price+'</p>'
	                    +'<p class="card-product__price">'+json[i].sale_price+'</p>'
	                  +'</div>'
	                +'</div>'
	              +'</div>'
				}
				$('#findList').html(jsonData);
			}
		})
	})
});
</script> 

  일단 검색을 하기 위해서 키보드에 검색어를 올리면 기존에 출력한 list의 내용들이 사라지게끔 hide()를 해준다. 

 

그리고 나서 css에서 받아온 값들을 변수에 저장해서, post방식으로 find.do에 넘겨준다. 

완료되면 find.do의 내용을 실행하고 그 결과값을 넘겨준다. result로 JSONArray를 String으로 변환한 값을 넘겼기 때문에, json을 파싱해서 변수에 담아준다. 

 

let json=JSON.parse(result);
				let jsonData='';
				for(let i=0; i<json.length; i++)
				{
					jsonData+='<div class="col-md-6 col-lg-4">'
		                +'<div class="card text-center card-product">' 
	                  +'<div class="card-product__img">'
	                   +'<img class="card-img" src="'+json[i].poster+'">'
	                    +'<ul class="card-product__imgOverlay">'
	                      +'<li><button><i class="ti-search"></i></button></li>'
	                      +'<li><button><i class="ti-shopping-cart"></i></button></li>'
	                      +'<li><button><i class="ti-heart"></i></button></li>'
	                    +'</ul>'
	                  +'</div>'
	                 
	                  +'<div class="card-body">'
	                    +'<p>'+json[i].category+'</p>'
	                    +'<h4 class="card-product__title">'+json[i].title+'</h4>'
	                    +'<p id="price">'+json[i].price+'</p>'
	                    +'<p class="card-product__price">'+json[i].sale_price+'</p>'
	                  +'</div>'
	                +'</div>'
	              +'</div>'
				}
				$('#findList').html(jsonData);

 

그리고 나서 jsonData라는 변수에 해당하는 css와 json값을 전부 넣어주고, 마지막에 데이터를 출력할 곳에 데이터를 뿌려주면 완성이 된다. 

 

 이렇게 뜬다. 화면 디자인이 아직 다 끝난게 아니라 여기를 좀 손봐야 할 것 같다. 

 

 

728x90
반응형