오늘은 이전글 다음글을 구현해보려고 한다.
글 이동은 게시글내용(게시글상세보기) 뷰에서 할 것이므로,
처음에는 bno(게시글PR)로 게시글 구분을 하니,
버튼에 onclick= "location.href='상세페이지링크/bno=${bno -1}'" 로
bno값을 불러와 +1, -1하면 되지 않나...라고 떠올렸지만,
구현해보니 삭제된 글 때문에 문제가 되었다..
1000번 글에서 이전글을보면 999번으로 가는데 999번글은 삭제해서 페이지가 제대로 나오지 않는다.
그래서 게시물 목록을 만들때 처럼,
ROW_NUMBER()로 정렬한 select한 결과를 서브쿼리로 select해서 이전글 다음글을 만들어야하나 생각하다가,
검색을 통해 더 간단한 방법을 찾았다.
[속성],
LEAD([속성],[이동값],[이동후값이없을경우 넣을 값]) OVER(ORDER BY [속성]) AS [지정해줄이름],
LAG([속성], ~~~~)
이다.
LEAD는 [속성]의 [이동값] 만큼 order by로 정렬한 값을 기준으로 + 해주고,
LAG는 - 해준다.
!!주의할점은 위에 select문안에 lead를 사용 할 [속성]을 넣어줘야 한다.
더이상 이동할 값이 없으면 [이동후값이없을경우 넣을 값]을 넣어준다.
Mapper 작성
<select id="movePage" parameterType="int" resultType="kr.co.vo.BoardVO">
select * from(SELECT
BNO,
LEAD(BNO,1,9999) OVER(ORDER BY BNO) AS next,
LAG(BNO,1,9999) OVER(ORDER BY BNO) AS last,
TITLE,
LEAD(TITLE,1,9999) OVER(ORDER BY BNO) AS nexttitle,
LAG(TITLE,1,9999) OVER(ORDER BY BNO) AS lasttitle
FROM MP_BOARD
order by BNO DESC)
WHERE BNO = #{bno}
</select>
해당 게시물PR(#{bno}) 를 기준으로, 윗글 아랫글 윗제목 밑제목을 구해준다.
게시글PR 만 파라미터로 필요하기 때문에, parameterType은 PR의 변수형인 int로 설정하고
resultType은 int값과 String값을 리턴해야 하기 때문에 간단하게 VO로 받겠다.
(기존 게시글의 VO를 이용)
VO작성
private int next;
private int last;
private String nexttitle;
private String lasttitle;
VO에 아까 as로 지정한 이름을 넣고, getter&setter를 만들어준다.
DAO작성
DAO
public BoardVO movePage(int bno)throws Exception;
DAOImpl
@Override
public BoardVO movePage(int bno)throws Exception{
return sqlsession.selectOne("boardMapper.movePage", bno);
}
쿼리에 필요한 bno값을 매개변수로 받고, sqlsession을 이용해 파라미터를 넘겨준다.
Service 작성
Service
public BoardVO movePage(int bno)throws Exception;
ServiceImpl
@Override
public BoardVO movePage(int bno)throws Exception{
return dao.movePage(bno);
}
Controller
@RequestMapping(value="/board/readView", method=RequestMethod.GET)
public String read(@ModelAttribute("scri") SearchCriteria scri,BoardVO boardVO, Model model) throws Exception{
logger.info("read");
model.addAttribute("read", service.read(boardVO.getBno()));
model.addAttribute("scri", scri);
model.addAttribute("replyVO",new ReplyVO());
List<Map<String, Object>> fileList = service.selectFileList(boardVO.getBno());
model.addAttribute("file", fileList);
model.addAttribute("move", service.movePage(boardVO.getBno()));
return "/board/readView";
}
상세페이지 뷰의 컨트롤러에는 bno가 들어가있는 boardVO를 뷰에서 파라미터로 받아오기 때문에
getBno로 service의 movePage에 매개변수로 넣어주고, 그 결과값을 move로 /board/readView(상세페이지)에서
사용한다.
게시글상세보기 뷰 (이전글 다음글이 들어갈 뷰) - JSTL, 부트스트랩 CDN 필요(글 뒤에 있음)
<div class="my-3 p-3 bg-white rounded shadow-sm">
<c:choose >
<c:when test="${move.next != 9999}">
<button type="button" class="btn btn-warning mr-3 mb-3" onclick="location.href='/board/readView?bno=${move.next}'"> <span class="glyphicon glyphicon-menu-up" aria-hidden="true"></span>다음글</button>
<a href="/board/readView?bno=${move.next}" style="color: black"> ${move.nexttitle} </a>
</c:when>
<c:when test="${move.next == 9999}">
<button type="button" class="btn btn-warning mr-3 mb-3" disabled>다음글이 없습니다</button>
</c:when>
</c:choose>
<br/>
<c:choose>
<c:when test="${move.last != 9999}">
<button type="button" class="btn btn-info mr-3 " onclick="location.href='/board/readView?bno=${move.last}'"> <span class="glyphicon glyphicon-menu-down" aria-hidden="true"></span>이전글</button>
<a href="/board/readView?bno=${move.last}" style="color: black"> ${move.lasttitle} </a>
</c:when>
<c:when test="${move.last == 9999}">
<button type="button" class="btn btn-info mr-3" disabled>이전글이 없습니다</button>
</c:when>
</c:choose>
</div>
button에 id나 name값을 달아서 <script>로 처리해도 되지만,
이번엔 JSTL을 사용해보았다.
<c:if> , <c:choose>에 대한 설명은 생략하겠다
java의 if , if else와 같다고 생각하면 되겠다.
컨트롤러에서 model로 move를 키로 보냈으니 move.next(다음글)와 move.last(이전글)를 사용 할 수 있다.
여기까지 했으면 이제 #${move.next} 등을 활용해서 원하는 위치에 값을 넣어 꾸미면 끝난다.
나는 button과 아이콘을 넣고, a href로 이전글,다음글 제목에도 링크를 넣어줬다.
이동값이 없으면 출력하는 9999가 값으로 나오면( ==9999 ),
버튼을 disabled하고 글이없습니다를 출력하도록 했다.
결과
********
<!-- 합쳐지고 최소화된 최신 CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<!-- 부가적인 테마 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
<!-- 합쳐지고 최소화된 최신 자바스크립트 -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
부트스트랩 CDN
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
JSTL CDN
'SPRING > IceWater Community' 카테고리의 다른 글
[스프링]게시판 조회수,댓글수 순 정렬과 게시글 10개,20개씩 보기 구현 (3) | 2021.09.07 |
---|---|
[스프링] 다중 게시판 구현 (CRUD) (1) | 2021.09.06 |
[스프링] ajax 댓글 에디터 및 이미지 삽입 구현 (0) | 2021.09.02 |
[스프링]게시판 글작성 에디터 적용과 파일미리보기,이미지 미리보기 (0) | 2021.08.30 |
[스프링] 첨부파일 다중파일 구현, 수정,삭제 로직의 설명(4) (2) | 2021.08.30 |