mybatis 동적쿼리 사용
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) 부분
@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>
== 최종 출력부분 ==
검색된 게시물만 출력되고, 페이지 네이션도 적절하게 출력되는 것을 확인 가능!
'JSP > JSP' 카테고리의 다른 글
[jsp] 결과갯수 배지 생성 / 내 게시물 출력 (사용자가 작성한 게시물) (0) | 2023.05.31 |
---|---|
[jsp] 파일입출력 (board 게시물에 추가) (0) | 2023.05.31 |
[jsp] list 페이징처리 (2) | 2023.05.31 |
[jsp] 댓글 6. 댓글 삭제 ( delete ) (0) | 2023.05.31 |
[jsp] 댓글 5. 댓글 수정 ( modify ) (0) | 2023.05.31 |