JSP/JSP 예제

[jsp] 검색기능

congs 2023. 5. 31. 12:19

mybatis 동적쿼리 사용

 

MYBATIS 동적쿼리.pptx
0.19MB

 

https://mybatis.org/mybatis-3/ko/dynamic-sql.html

 

MyBatis – 마이바티스 3 | 동적 SQL

동적 SQL 마이바티스의 가장 강력한 기능 중 하나는 동적 SQL을 처리하는 방법이다. JDBC나 다른 유사한 프레임워크를 사용해본 경험이 있다면 동적으로 SQL 을 구성하는 것이 얼마나 힘든 작업인지

mybatis.org

 

1. board폴더 list.jsp 에 검색부분 추가 : 화면 출력

  • 작성 위치 : <body>태그안, 출력 테이블 상단

<form action="/brd/page" method="post">
		<div>
		<c:set value="${pgh.pgvo.type }" var="typed"></c:set>
			<select name="type">
				<option ${typed == null? 'selected': ''}>choose 선택하세요</option>
				<!-- selected = 현재 내가 선택한 값 -->
				<option value="t">title 제목</option>
				<option value="c">content 내용</option>
				<option value="w">writer 작성자</option>
				<option value="tc">title or contnent 제목/내용</option>
				<option value="tw">title or writer 제목/작성자</option>
				<option value="cw">content or writer 내용/작성자</option>
				<option value="tcw">all 전체</option>
			</select>
			<input type="text" name="keyword" placeholder="Search 검색내용 입력">
			<button type="submit">Search 검색</button>
		</div>
	
	</form>

 


 

2. PagingVO에 검색부분 추가 (멤버변수, getter/setter등)

  • 추가위치 : 마음대로! 맨아래에 넣긴했음

private String keyword;
	private String type;


	//타입이 2개인경우
	public String[] getTypeToArray() {
		return this.type == null ? new String[] {} : this.type.split("");
	}
	
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getKeyword() {
		return keyword;
	}
	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}
	
	@Override
	public String toString() {
		return "PagingVO [pageNo=" + pageNo + ", qty=" + qty + ", keyword=" + keyword + ", type=" + type + "]";
	}

 


 

3. boardController에서 case "page"에 추가

- case "page" 추가부분

//검색
String type ="";
String keyword="";
				
if(request.getParameter("type") != null) {
	type = request.getParameter("type");
	keyword = request.getParameter("keyword");
	log.info(">>> type : " + type + "/  >>> ketword: " + keyword);
					
}



pgvo.setType(type);
pgvo.setKeyword(keyword);
log.info(">>> pgvo set설정확인: "+pgvo.toString());




List<BoardVO> list = bsv.getPageList(pgvo);

- 전체 case "page"

case "page":
			try {
				int pageNo = 1;
				int qty = 10;
				
				//검색
				String type ="";
				String keyword="";
				
				if(request.getParameter("type") != null) {
					type = request.getParameter("type");
					keyword = request.getParameter("keyword");
					log.info(">>> type : " + type + "/  >>> ketword: " + keyword);
					
				}
				
				
				if(request.getParameter("pageNo") != null) {
					pageNo = Integer.parseInt(request.getParameter("pageNo")); 
					qty = Integer.parseInt(request.getParameter("qty")); 
				}
				PagingVO pgvo = new PagingVO(pageNo, qty);
				
				pgvo.setType(type);
				pgvo.setKeyword(keyword);
				log.info(">>> pgvo set설정확인: "+pgvo.toString());
				
				//전체 페이지의 개수
				int totCount = bsv.getTotal(pgvo);
				log.info("전체페이지의 수: "+totCount);
				
				//limit을 이용해 맞는 select List호출!
				//startPage, qty
				List<BoardVO> list = bsv.getPageList(pgvo);
				log.info(">>> list.size: "+ list.size());
				
				PagingHandler ph = new PagingHandler(pgvo, totCount);
				request.setAttribute("pgh", ph);
				request.setAttribute("list", list);
				log.info("pageList 성공");
				
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			destPage = "/board/list.jsp";
			break;

 


 

4. controller에서 연결 부분 변경 : getTotal(pgvo), getPageList(pgvo) 부분

service


serviceImpl


DAO


DAOImpl

@Override
	public int getTotal(PagingVO pgvo) {
		log.info(">>> getTotal DAO 진입");
		return sql.selectOne(BS+"cnt", pgvo);
	}

	@Override
	public List<BoardVO> getPageList(PagingVO pgvo) {
		log.info(">>> getPageList DAO 진입");
//		return sql.selectList(BS+"pageList",pgvo);
		return sql.selectList(BS+"selectList",pgvo);
	
	}

5. Mapper에 추가 및 변경!

  • cnt부분 변경
  • sql id="search" 생성
  • selectList 생성

<select id="cnt" resultType="int" parameterType="pgvo">
  		select count(bno) from board where bno>0
  		<include refid="search"></include>	<!-- sql id='search'를 붙여줘 -->
  	</select>
  	
  	
  	<sql id="search">
  		<if test="type != null">
  			<trim prefix="and (" suffix=")" prefixOverrides="OR"> 
  			<!-- 조건이 있다면 and( 글자 ) 붙이기, and()괄호 안에 OR이 있다면 삭제 -->
  				<foreach collection="typeToArray" item="type"> <!-- 내가 지금 돌릴 값 -->
  					<trim prefix="OR"> <!-- 여러개가 있다면 OR -->
  						<choose>
  							<when test="type == 't'.toString()"> <!-- type의 값이 t라면 -->
  								title like concat('%', #{keyword}, '%')
  								 <!-- keyword가 앞뒤 어디든 와도 상관없어요 -->
  							</when>
  							<when test="type == 'w'.toString()"> 
  								writer like concat('%', #{keyword}, '%')
  							</when>
  							<when test="type == 'c'.toString()"> 
  								content like concat('%', #{keyword}, '%')
  							</when>
  						</choose>
  					</trim>
  				</foreach>
  			</trim>
  		</if>
  	</sql>
  	
  	<select id="selectList" parameterType="pgvo" resultType="bvo">
  		select a.bno, title, writer, reg_date, count from (
  			select bno from board where bno>0
  			<include refid="search"></include>
  			order by bno desc
  			limit #{pageStart}, #{qty}
  		) a left join board b
  		on a.bno = b.bno
  	</select>

 


 

 

== 현재까지 출력화면 ==

 


이제! 출력이 되지만,  2페이지를 누르면 검색부분이 리셋됨! -> list.jsp에서 고쳐보자!

 


 

== list.jsp ==

 

6.  검색을 유지하면서 다음페이지로 넘어가도록 설정 추가!

                -> list.jsp(출력화면)에서

 

( 검색 부분 )

<!-- 검색 -->
	<form action="/brd/page" method="post">
		<div>
		<c:set value="${pgh.pgvo.type }" var="typed"></c:set>
			<select name="type">
				<option ${typed == null? 'selected': ''}>choose 선택하세요</option>
				<!-- selected = 현재 내가 선택한 값 -->
				<option value="t" ${typed eq 't' ? 'selected' : ''}>title 제목</option>
				<option value="c" ${typed eq 'c' ? 'selected' : ''}>content 내용</option>
				<option value="w" ${typed eq 'w' ? 'selected' : ''}>writer 작성자</option>
				<option value="tc" ${typed eq 'tc' ? 'selected' : ''}>title or contnent 제목/내용</option>
				<option value="tw" ${typed eq 'tw' ? 'selected' : ''}>title or writer 제목/작성자</option>
				<option value="cw" ${typed eq 'cw' ? 'selected' : ''}>content or writer 내용/작성자</option>
				<option value="tcw" ${typed eq 'tcw' ? 'selected' : ''}>all 전체</option>
			</select>
			<input type="text" name="keyword" placeholder="Search 검색내용 입력" value="${pgh.pgvo.keyword}>
			<input type="hidden" name="pageNo" value="1">
			<input type="hidden" name="qty" value="${pgh.pgvo.qty }">
			<button type="submit">Search 검색</button>
		</div>
	
	</form>

 

(페이지 네이션 부분)

   <!-- 페이지네이션의 위치 -->
	<!-- 이전페이지 -->
	<c:if test="${pgh.prev }">
	<a href="/brd/page?pageNo=${pgh.startPage-1 }&qty=${pgh.pgvo.qty}
		&type=${pgh.pgvo.type}&keyword=${pgh.pgvo.keyword}">이전</a> 
	</c:if>
	
	<!-- controller에서 page의 정보를 싣고 와야 츨력~! -->
	<!-- 1~endpage까지 숫자 반복 -->
	<c:forEach begin="${pgh.startPage }" end="${pgh.endPage }" var="i">
		<a href="/brd/page?pageNo=${i }&qty=${pgh.pgvo.qty}
			&type=${pgh.pgvo.type}&keyword=${pgh.pgvo.keyword}">${i }  |</a>
	</c:forEach>
	
	<!-- 다음페이지 -->
	<c:if test="${pgh.next }">
	<a href="/brd/page?pageNo=${pgh.endPage+1 }&qty=${pgh.pgvo.qty}
		&type=${pgh.pgvo.type}&keyword=${pgh.pgvo.keyword}">다음</a> 
	</c:if>

 

(list.jsp 전체 코드)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>List 전체출력페이지</title>

	</head>
<body>
	<h1>list 전체 출력</h1>
	
	<br><br>
	
	<!-- 검색 -->
	<form action="/brd/page" method="post">
		<div>
		<c:set value="${pgh.pgvo.type }" var="typed"></c:set>
			<select name="type">
				<option ${typed == null? 'selected': ''}>choose 선택하세요</option>
				<!-- selected = 현재 내가 선택한 값 -->
				<option value="t" ${typed eq 't' ? 'selected' : ''}>title 제목</option>
				<option value="c" ${typed eq 'c' ? 'selected' : ''}>content 내용</option>
				<option value="w" ${typed eq 'w' ? 'selected' : ''}>writer 작성자</option>
				<option value="tc" ${typed eq 'tc' ? 'selected' : ''}>title or contnent 제목/내용</option>
				<option value="tw" ${typed eq 'tw' ? 'selected' : ''}>title or writer 제목/작성자</option>
				<option value="cw" ${typed eq 'cw' ? 'selected' : ''}>content or writer 내용/작성자</option>
				<option value="tcw" ${typed eq 'tcw' ? 'selected' : ''}>all 전체</option>
			</select>
			<input type="text" name="keyword" placeholder="Search 검색내용 입력" value="${pgh.pgvo.keyword}>
			<input type="hidden" name="pageNo" value="1">
			<input type="hidden" name="qty" value="${pgh.pgvo.qty }">
			<button type="submit">Search 검색</button>
            <span>${ph.totalCount}</span>
		</div>
	
	</form>
	 
	 <br><br>
	
	<table class="table table-hover">
		<thead>
			<tr>
				<th>bno</th>
				<th>title 제목</th>
				<th>writer 작성자</th>
				<th>reg_date 작성일자</th>				
				<th>count 조회수</th>				
			</tr>
		</thead>
		
		<tbody>
			<c:forEach items="${list }" var="list">
			<tr>
				<td>${list.bno }</td>
				<td><a href="detail?bno=${list.bno}">${list.title }</a></td>
				<td>${list.writer }</td>
				<td>${list.reg_date }</td>
				<td>${list.count }</td>
			</tr>
			</c:forEach>
		</tbody>
	</table>
	
	
	
	<!-- 페이지네이션의 위치 -->
	<!-- 이전페이지 -->
	<c:if test="${pgh.prev }">
	<a href="/brd/page?pageNo=${pgh.startPage-1 }&qty=${pgh.pgvo.qty}
		&type=${pgh.pgvo.type}&keyword=${pgh.pgvo.keyword}">이전</a> 
	</c:if>
	
	<!-- controller에서 page의 정보를 싣고 와야 츨력~! -->
	<!-- 1~endpage까지 숫자 반복 -->
	<c:forEach begin="${pgh.startPage }" end="${pgh.endPage }" var="i">
		<a href="/brd/page?pageNo=${i }&qty=${pgh.pgvo.qty}
			&type=${pgh.pgvo.type}&keyword=${pgh.pgvo.keyword}">${i }  |</a>
	</c:forEach>
	
	<!-- 다음페이지 -->
	<c:if test="${pgh.next }">
	<a href="/brd/page?pageNo=${pgh.endPage+1 }&qty=${pgh.pgvo.qty}
		&type=${pgh.pgvo.type}&keyword=${pgh.pgvo.keyword}">▶</a> 
	</c:if>
	
	<br><br><br>
	<a href="/"><button>기본화면으로 돌아가기</button></a>
	
	
	
</body>
</html>

 

 


 

== 최종 출력부분 ==

 


검색된 게시물만 출력되고, 페이지 네이션도 적절하게 출력되는 것을 확인 가능!