본문 바로가기
Java/Servlet & JSP

JSP) 검색기능 구현하기

by 박채니 2022. 7. 1.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


검색기능 구현하기

 

memberList.jsp

(회원리스트 코드는 생략)

<%@page import="com.ce.mvc2.member.model.dto.Gender"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@page import="java.text.DecimalFormat"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/views/common/header.jsp" %>
<%
	List<Member> memberList = (List<Member>)request.getAttribute("memberList");
%>
<!-- 관리자용 admin.css link -->
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/admin.css" />
<style>
div#search-container {
	width:100%;
	margin: 0 0 10px 0;
	padding: 3px;
	background-color: rgba(0,188,212, .3);
}
div#search-memberId {
	display:inline-block;
}
div#search-memberName {
	display: none;
}
div#search-gender {
	display: none;
}
</style>
<script>
window.addEventListener('load', (e) => {
	document.querySelector("#searchType").onchange = (e) => {
		document.querySelectorAll(".search-type").forEach((div) => {
			div.style.display = 'none';
		});
		
		let id;
		switch(e.target.value) {
		case "member_id" : id="memberId"; break;
		case "member_name" : id="memberName"; break;
		case "gender" : id="gender"; break;
		}
		document.querySelector(`#search-\${id}`).style.display = 'inline-block';
	}
});
</script>
<section id="memberList-container">
	<h2>회원관리</h2>
	<div id="search-container">
        <label for="searchType">검색타입 :</label> 
        <select id="searchType">
            <option value="member_id">아이디</option>        
            <option value="member_name">회원명</option>
            <option value="gender">성별</option>
        </select>
        <div id="search-memberId" class="search-type">
            <form action="<%=request.getContextPath()%>/admin/memberFinder">
                <input type="hidden" name="searchType" value="member_id"/>
                <input type="text" name="searchKeyword"  size="25" placeholder="검색할 아이디를 입력하세요."/>
                <button type="submit">검색</button>            
            </form>    
        </div>
        <div id="search-memberName" class="search-type">
            <form action="<%=request.getContextPath()%>/admin/memberFinder">
                <input type="hidden" name="searchType" value="member_name"/>
                <input type="text" name="searchKeyword" size="25" placeholder="검색할 이름을 입력하세요."/>
                <button type="submit">검색</button>            
            </form>    
        </div>
        <div id="search-gender" class="search-type">
            <form action="<%=request.getContextPath()%>/admin/memberFinder">
                <input type="hidden" name="searchType" value="gender"/>
                <input type="radio" name="searchKeyword" value="M" checked> 남
                <input type="radio" name="searchKeyword" value="F"> 여
                <button type="submit">검색</button>
            </form>
        </div>
    </div>

※ header.jsp에 window.onload가 존재하기 때문에, memberList.jsp에서도 window.onload를 사용하면 덮어씌워져서 addEventListener를 사용하여 header.jsp내에 존재하는 "msg"출력이 잘 되도록 처리!!

 

java script을 통해서 검색타입이 바뀌는 것에 따라 그에 따른 폼이 표시되도록 하였습니다.

 

관리자가 검색 타입을 지정하고 검색하고자 하는 아이디/이름/성별을 입력한 후 검색하면 /admin/memberFinder 서블릿이 실행됩니다.

이 때, hidden 타입으로 DB 컬럼별칭과 동일한 value값 (searchType)을 같이 제출하여 사용할 수 있도록 하였습니다.

 

Controller

AdminMemberFinder

@WebServlet("/admin/memberFinder")
public class AdminMemberFinder extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private MemberService memberService = new MemberService();
	
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			// 1. 사용자 입력값 처리
			String searchType = request.getParameter("searchType");
			String searchKeyword = request.getParameter("searchKeyword");
			Map<String, Object> param = new HashMap<>();
			param.put("searchType", searchType);
			param.put("searchKeyword", searchKeyword);
			
			// 2. 업무로직
			List<Member> memberList = memberService.findMemberLike(param);
			
			// 3. view단 처리
			request.setAttribute("memberList", memberList);
			request.getRequestDispatcher("/WEB-INF/views/admin/memberList.jsp").forward(request, response);
			
		} catch(Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
}

 

Service

MemberService

public List<Member> findMemberLike(Map<String, Object> param) {
    Connection conn = getConnection();
    List<Member> memberList = memberDao.findMemberLike(conn, param);
    close(conn);
    return memberList;
}

 

Dao

MemberDao

// findMemberLike = select * from member where # like ?
public List<Member> findMemberLike(Connection conn, Map<String, Object> param) {
    PreparedStatement pstmt = null;
    ResultSet rset = null;
    List<Member> memberList = new ArrayList<>();
    String sql = prop.getProperty("findMemberLike");
    sql = sql.replace("#", (String)param.get("searchType"));

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, "%" + param.get("searchKeyword") + "%");
        rset = pstmt.executeQuery();
        while(rset.next()) {
            memberList.add(handleMemberResultSet(rset));
        }
    } catch (SQLException e) {
        throw new MemberException("관리자 회원 검색 오류!", e);
    } finally {
        close(rset);
        close(pstmt);
    }
    return memberList;
}

컬럼명, 테이블명은 setString으로 처리가 불가하므로 replace() 메소드를 이용하여 먼저 처리해주었습니다.

검색타입/검색어에 따라 보여지는 회원정보가 달라지는 것을 확인할 수 있습니다.

 

memberList.jsp

<%
List<Member> memberList = (List<Member>)request.getAttribute("memberList");
String type = request.getParameter("searchType");
String kw = request.getParameter("searchKeyword");
%>
<!-- 관리자용 admin.css link -->
<link rel="stylesheet" href="<%=request.getContextPath()%>/css/admin.css" />
<style>
div#search-container {
width:100%;
margin: 0 0 10px 0;
padding: 3px;
background-color: rgba(0,188,212, .3);
}
div#search-memberId {
display: <%= type == null || "member_id".equals(type) ? "inline-block" : "none" %>;
}
div#search-memberName {
display: <%= "member_name".equals(type) ? "inline-block" : "none" %>;
}
div#search-gender {
display: <%= "gender".equals(type) ? "inline-block" : "none" %>;
}
</style>
<script>
window.onload = (e) => {
document.querySelector("#searchType").onchange = (e) => {
    document.querySelectorAll(".search-type").forEach((div) => {
        div.style.display = 'none';
    });

    let id;
    switch(e.target.value) {
    case "member_id" : id="memberId"; break;
    case "member_name" : id="memberName"; break;
    case "gender" : id="gender"; break;
    }
    document.querySelector(`#search-\${id}`).style.display = 'inline-block';
}
}
</script>
<section id="memberList-container">
<h2>회원관리</h2>
<div id="search-container">
    <label for="searchType">검색타입 :</label> 
    <select id="searchType">
        <option value="member_id" <%= "member_id".equals(type) ? "selected" : "" %>>아이디</option>        
        <option value="member_name" <%= "member_name".equals(type) ? "selected" : "" %>>회원명</option>
        <option value="gender" <%= "gender".equals(type) ? "selected" : "" %>>성별</option>
    </select>
    <div id="search-memberId" class="search-type">
        <form action="<%=request.getContextPath()%>/admin/memberFinder">
            <input type="hidden" name="searchType" value="member_id"/>
            <input type="text" name="searchKeyword"  size="25" placeholder="검색할 아이디를 입력하세요."
                value="<%= "member_id".equals(type) ? kw : "" %>" />
            <button type="submit">검색</button>            
        </form>    
    </div>
    <div id="search-memberName" class="search-type">
        <form action="<%=request.getContextPath()%>/admin/memberFinder">
            <input type="hidden" name="searchType" value="member_name"/>
            <input type="text" name="searchKeyword" size="25" placeholder="검색할 이름을 입력하세요."
                value="<%= "member_name".equals(type) ? kw : "" %>" />
            <button type="submit">검색</button>            
        </form>    
    </div>
    <div id="search-gender" class="search-type">
        <form action="<%=request.getContextPath()%>/admin/memberFinder">
            <input type="hidden" name="searchType" value="gender"/>
            <input type="radio" name="searchKeyword" value="M" <%= "gender".equals(type) && "M".equals(kw) ? "checked" : ""%> > 남
            <input type="radio" name="searchKeyword" value="F" <%= "gender".equals(type) && "F".equals(kw) ? "checked" : ""%>> 여
            <button type="submit">검색</button>
        </form>
    </div>
</div>

검색타입에 따라 보여지는 form이 달라지도록 하였으며, 선택한 타입과 검색어가 그대로 유지되도록 하였습니다.