[Spring Boot] 게시판 검색 기능

고운·2023년 5월 23일
0

Spring Boot

목록 보기
7/13
post-custom-banner

검색 기능

페이징 기능이 구현되어 있는 상태에서 검색 기능 추가하기

View

<form action="listGoods" id="f">
	<select name="searchColumn" id="searchColumn">
		<option value="no">상품번호</option>
		<option value="name" selected="selected">상품명</option>
		<option value="price">가격</option>
		<option value="qty">수량</option>
		<option value="fname">이미지</option>
	</select>
	<select id="op" name="op">
		<option value="=">=</option>
		<option value=">=">>=</option>
		<option value="<="><=</option>
		<option value=">">></option>
		<option value="<"><</option>
		<option value="!=">!=</option>
	</select>
	<input type="search" name="keyword" id="keyword">
	<input type="submit" value="검색">
</form>
<button id="reset">검색 초기화</button><br>

JS

카테고리가 상품명일 경우 op(operator)가 보이지 않고 나머지 카테고리는 op가 보이게 설정

$("#searchColumn").change(function(){
	var c_name=$(this).val();
	if(c_name=="name"){
		$("#op").css("display","none")
	}else{
		$("#op").css("display","inline");
	}
})

Controller

매개변수로 받아오기

@GetMapping("/listGoods")
	public void list(
			Model model, 
			@RequestParam(value="pageNUM",defaultValue="1") int pageNUM,
			String orderColumn,
			HttpSession session,
			String keyword,
			String searchColumn,
			String op,
			String reset
			) {

마지막에 세션에 검색 조건들을 저장

session.setAttribute("session_column", session_column);
session.setAttribute("keyword", keyword);
session.setAttribute("searchColumn", searchColumn);
session.setAttribute("op", op);

정렬할 칼럼을 무엇으로 할지 정하기

매개변수로 전달된 orderColumn이 있으면 그것을 사용하고 없으면 세션에 저장된 칼럼을 가져온다.

//초기화
String session_column=null;

//세션에 저장된 orderColumn이 있으면
if(session.getAttribute("session_column")!=null) {
	session_column=(String)session.getAttribute("session_column");
}
//요청에 orderColumn이 있으면 session에 저장된 칼럼보다 우선하므로 session_column의 값을 orderColumn으로 갈아끼워 준다.
if(orderColumn!=null && !orderColumn.equals("")) {
	session_column=orderColumn;
}

keyword와 searchColunm, op도 위와 같은 방식으로 해도 되고 아래처럼 해도 된다.

세션에 있는 검색어가 필요한 경우는? :
새로운 검색어가 없고, 세션에 저장된 키워드가 있을 때

⇒ keyword에 세션에 저장된 keyword를 대입

searchColumn에 세션에 저장된 searchColumn을 대입

searchColumn이 전달되었고 그게 상품명(name)이 아니라면 op도 세션에서 가져와야 함

아닐 경우 요청에 포함된 keyword, searchColumn, op를 그대로 사용하면 된다. (요청에서 전달해준 keyword, searchColumn, op가 세션에 저장된 것보다 우선해야 하므로)


if(session.getAttribute("keyword")!=null && (keyword==null || keyword.equals(""))) {
	keyword=(String)session.getAttribute("keyword");
	searchColumn=(String)session.getAttribute("searchColumn");
	if(searchColumn!=null && !searchColumn.equals("name")) {
		op=(String)session.getAttribute("op");
	}
}

HashMap을 생성해서 검색 관련 변수들을 넣고, findAll에 전달해준다.

HashMap<String, Object> map=new HashMap<>();

map.put("orderColumn", session_column);
map.put("keyword", keyword);
map.put("searchColumn", searchColumn);
map.put("op", op);

model.addAttribute("list", dao.findAll(map));

검색 버튼 클릭 시 사용자가 입력했던 keyword, searchColumn등이 결과 페이지에도 그대로 남아있게 만들기

form을 submit할 때, 입력된 value들을 sessionStorage에 저장한다.

$("#f").submit(function(){
	var searchColumn=$("#searchColumn").val();
	var op=$("#op").val();
	var keyword=$("#keyword").val();
	
	sessionStorage.setItem("searchColumn",searchColumn);
	sessionStorage.setItem("op",op);
	sessionStorage.setItem("keyword",keyword);
});

저장된 아이템들을 불러와서 변수에 저장한다.

var sc=sessionStorage.getItem("searchColumn");
var op=sessionStorage.getItem("op");
var keyword=sessionStorage.getItem("keyword");

검색버튼 누른 다음 화면에서 세션에서 가져온 value들이 보여지게 설정하고 칼럼에 따라 op가 보이거나 안 보이게 설정

$("#searchColumn > option[value="+sc+"]").attr("selected","selected");
$("#op > option[value='"+op+"']").attr("selected","selected");
if(keyword!=null){
	$("#keyword").val(keyword);
}

if(sc==null || sc=='null' || sc=="name"){
	$("#op").css("display","none");
}else{
	$("#op").css("display","inline");
}

검색 결과 리셋 기능

리셋버튼 만들기

<button id="reset">검색 초기화</button><br>

리셋버튼 누르면 세션에 저장된 아이템들을 지우고 쿼리스트링으로 reset=yes를 전달

$("#reset").click(function(){
	sessionStorage.removeItem("searchColumn");
	sessionStorage.removeItem("op");
	sessionStorage.removeItem("keyword");
	
	location.href="listGoods?reset=yes";
})

reset=”yes” 일 경우 session에 담긴 검색 관련 정보들을 삭제

if (reset!=null && reset.equals("yes")) {
			session.removeAttribute("searchcolumn");
			session.removeAttribute("keyword");
			session.removeAttribute("op");
		}

Mapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="goods">
  <select id="findAll" resultType="goodsVO" parameterType="java.util.HashMap">
    select no,name,price,qty,fname from
	(select rownum n, a.* from
	(select * from goods 
	<if test="keyword!=null and keyword!=''">
		<if test="searchColumn=='name'">
			where name like '%' || #{keyword} || '%'
		</if>
		<if test="searchColumn!='name'">
			where ${searchColumn} ${op} #{keyword}
		</if>
	</if>
	<if test="orderColumn!=null and orderColumn!=''">
		order by ${orderColumn}
	</if>
	) a)
	where n between #{start} and #{end} 
  </select>
  <select id="total" resultType="java.lang.Integer" parameterType="java.util.HashMap">
  	select count(*) from goods 
  	<if test="keyword!=null and keyword!=''">
	  	<if test="searchColumn=='name'">
			where name like '%' || #{keyword} || '%'
		</if>
		<if test="searchColumn!='name'">
			where ${searchColumn} ${op} #{keyword}
		</if>
  	</if>
  </select>
</mapper>

전체 코드 (페이징 +검색)

controller

int pageSIZE=4;
int totalRecord=0;
int totalPage=1;

@Autowired
private GoodsDAO dao;

public void setDao(GoodsDAO dao) {
	this.dao = dao;
}

@GetMapping("/listGoods")
public void list(
		Model model, 
		@RequestParam(value="pageNUM",defaultValue="1") int pageNUM,
		String orderColumn,
		HttpSession session,
		String keyword,
		String searchColumn,
		String op,
		String reset
		) {
	System.out.println("searchColumn:"+searchColumn);
//HttpSession import 할 때 javax.servlet.http.HttpSession <- ver 2.7.0
//	jakarta.servlet.http.HttpSession <-ver 3.0.0 <-이거 써야 함
/*	
 * ↓ 이것의 버전
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>3.0.0</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>
*/
	if (reset!=null && reset.equals("yes")) {
		session.removeAttribute("searchcolumn");
		session.removeAttribute("keyword");
		session.removeAttribute("op");
	}
	
	String session_column=null;
	
	if(session.getAttribute("session_column")!=null) {
		session_column=(String)session.getAttribute("session_column");
	}
	if(orderColumn!=null && !orderColumn.equals("")) {
		session_column=orderColumn;
	}
	
	//언제 세션에 있는 검색어를 갖고 오느냐?
	//새로운 검색어가 없고, 세션에 저장된 키워드가 있을 때
	if(session.getAttribute("keyword")!=null && (keyword==null || keyword.equals(""))) {
		keyword=(String)session.getAttribute("keyword");
		searchColumn=(String)session.getAttribute("searchColumn");
		if(searchColumn!=null && !searchColumn.equals("name")) {
			op=(String)session.getAttribute("op");
		}
	}
	
	HashMap<String, Object> map=new HashMap<>();

	map.put("orderColumn", session_column);
	map.put("keyword", keyword);
	map.put("searchColumn", searchColumn);
	map.put("op", op);
	
	
	totalRecord=dao.getTotalRecord(map);
	totalPage=(int)Math.ceil((double)totalRecord/pageSIZE);
	
	int start=(pageNUM-1)*pageSIZE+1;
	int end=pageNUM*pageSIZE;
	if (end>totalRecord) {
		end=totalRecord;
	}
	
	map.put("start", start);
	map.put("end", end);
	
	System.out.println("pageNUM: "+pageNUM);
	System.out.println("orderColumn:"+orderColumn);
	System.out.println("totalPage: "+totalPage);
	System.out.println("keyword: "+keyword);
	System.out.println("searchColumn:"+searchColumn);
	System.out.println("------------------------------");
	
	model.addAttribute("totalPage", totalPage);
	model.addAttribute("list", dao.findAll(map));
	
	session.setAttribute("session_column", session_column);
	session.setAttribute("keyword", keyword);
	session.setAttribute("searchColumn", searchColumn);
	session.setAttribute("op", op);

}

JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
	.highlight{
		background:pink;
	}
	#op{
		display:none;
	}
	#f{
		display:inline;
	}
	#reset{
		display:inline;
	}
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script type="text/javascript">
	$(function(){
		$(".item").hover(function(){
			$(this).addClass("highlight");
		},function(){
			$(this).removeClass("highlight");
		});
		
		$(".item").click(function(){
			var no=$(this).attr("no");
			location.href="detailGoods?no="+no;
		});
		
		$("#searchColumn").change(function(){
			var c_name=$(this).val();
			if(c_name=="name"){
				$("#op").css("display","none")
			}else{
				$("#op").css("display","inline");
			}
		})
		
		$("#f").submit(function(){
			var searchColumn=$("#searchColumn").val();
			var op=$("#op").val();
			var keyword=$("#keyword").val();
			
			sessionStorage.setItem("searchColumn",searchColumn);
			sessionStorage.setItem("op",op);
			sessionStorage.setItem("keyword",keyword);
		});
		
		var sc=sessionStorage.getItem("searchColumn");
		var op=sessionStorage.getItem("op");
		var keyword=sessionStorage.getItem("keyword");
		
		
		$("#searchColumn > option[value="+sc+"]").attr("selected","selected");
		$("#op > option[value='"+op+"']").attr("selected","selected");
		if(keyword!=null){
			$("#keyword").val(keyword);
		}
		
		if(sc==null || sc=='null' || sc=="name"){
			$("#op").css("display","none");
		}else{
			$("#op").css("display","inline");
		}
		
		$("#reset").click(function(){
			sessionStorage.removeItem("searchColumn");
			sessionStorage.removeItem("op");
			sessionStorage.removeItem("keyword");
			
			location.href="listGoods?reset=yes";
		})
	});
</script>
</head>
<body>
	<h2>상품 목록</h2>
	<hr>
	<a href="insertGoods">상품 등록</a><br>
	<form action="listGoods" id="f">
		<select name="searchColumn" id="searchColumn">
			<option value="no">상품번호</option>
			<option value="name" selected="selected">상품명</option>
			<option value="price">가격</option>
			<option value="qty">수량</option>
			<option value="fname">이미지</option>
		</select>
		<select id="op" name="op">
			<option value="=">=</option>
			<option value=">=">>=</option>
			<option value="<="><=</option>
			<option value=">">></option>
			<option value="<"><</option>
			<option value="!=">!=</option>
		</select>
		<input type="search" name="keyword" id="keyword">
		<input type="submit" value="검색">
	</form>
	<button id="reset">검색 초기화</button><br>
	<table border='1'>
		<tr>
			<td><a href="listGoods?orderColumn=no">상품번호</a></td>
			<td><a href="listGoods?orderColumn=name">상품명</a></td>
			<td><a href="listGoods?orderColumn=price">가격</a></td>
			<td><a href="listGoods?orderColumn=qty">수량</a></td>
			<td><a href="listGoods?orderColumn=fname">이미지</a></td>
		</tr>
		<c:forEach var="g" items="${list }">
			<tr class="item" no="${g.no}">
				<td>${g.no }</td>
				<td>${g.name }</td>
				<td>${g.price }</td>
				<td>${g.qty }</td>
				<td>${g.fname }</td>
			</tr>
		</c:forEach>
	</table>
		
	
		
	<hr>
	<c:forEach var="i" begin="1" end="${totalPage }">
		<a href="listGoods?pageNUM=${i }">${i }</a>&nbsp;&nbsp;
	</c:forEach>
</body>
</html>
profile
백엔드 개발자
post-custom-banner

0개의 댓글