본문 바로가기

프로그래밍 기초/SPRING

[Spring]게시물 이전글,다음글 보기 기능 구현

목표

글 목록보기에서 제목을 누르면 들어가지는 detail(카페 글 상세보기)에서 이전글과 다음글을 볼 수 있는 링크를 단다.

이 때 글 목록에 검색조건이 있는 상태라면 detail에서도 적용시킨다. 

 

 


 

게시물 이전글,다음글 보기 기능 구현

DTO

DTO에 이전글과 다음글을 담을 변수 추가한다. 

	private int prevNum; //이전글의 글번호를 담을 필드
	private int nextNum; //다음글의 글번호를 담을 필드

detail.jsp

글자세히 보기인 detail.jsp에 이전글과 다음글이 있는 경우 보이는

링크를 추가한다.이때 condition과 keyword parameter값을 넘겨준다.

	<c:if test="${dto.prevNum ne 0 }">
		<a href="detail.do?num=${dto.prevNum }&condition=${condition}&keyword=${encodedKeyword}">이전글</a>
	</c:if>
	
	<c:if test="${dto.nextNum ne 0 }">
		<a href="detail.do?num=${dto.nextNum }&condition=${condition}&keyword=${encodedKeyword}">다음글</a>
	</c:if>	

 


Controller

Controller에서 datail의 요청을 어떻게 처리할지 정의한다. 

service의 getDatail메소드를 호출하기로 한다.

	//글 자세히 보기 요청 처리
	@RequestMapping("/cafe/detail")
	public String detail(HttpServletRequest request){
		service.getDetail(request);
		//view page 로 forward 이동해서 글 자세히 보기 
		return "cafe/detail";
	}

참고 : LAG는 이전글번호 LEAD 는 다음글번호를 출력한다.


Service

Service의 getDatail메소드에서 dto1을 생성한다.

request객체에서 얻어온 파라미터 num, keyword, codition을 dto에집어넣는다.

num:선택한 글번호/keyword와 codition:입력한 검색조건

dto을 인자로 갖는 dao.getData메소드를 호출하여 검색조건에 해당되는 dto2에 담는다. =>아래 Mapper참고

dto2에는 검색조건에 영향을 받은 (num, writer, title, content, viewCount, regdate,prevNum,nextNum)가 담겨있다.

dto2를 request객체에 담는다.

@Override
	public void getDetail(HttpServletRequest request) {
		//파라미터로 전달되는 글번호
		int num=Integer.parseInt(request.getParameter("num"));
		
		//검색과 관련된 파라미터를 읽어와 본다.
		String keyword=request.getParameter("keyword");
		String condition=request.getParameter("condition");
		
		//CafeDto 객체 생성 (select 할때 필요한 정보를 담기 위해)
		CafeDto dto=new CafeDto();
		
		if(keyword != null) {//검색 키워드가 전달된 경우
			if(condition.equals("titlecontent")) {//제목+내용 검색
				dto.setTitle(keyword);
				dto.setContent(keyword);
			}else if(condition.equals("title")) {//제목 검색
				dto.setTitle(keyword);
			}else if(condition.equals("writer")) {//작성자 검색
				dto.setWriter(keyword);
			}
			//request 에 검색 조건과 키워드 담기
			request.setAttribute("condition", condition);
			/*
			 *  검색 키워드에는 한글이 포함될 가능성이 있기 때문에
			 *  링크에 그대로 출력가능하도록 하기 위해 미리 인코딩을 해서
			 *  request 에 담아준다.
			 */
			String encodedKeyword=null;
			try {
				encodedKeyword=URLEncoder.encode(keyword, "utf-8");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			//인코딩된 키워드와 인코딩 안된 키워드를 모두 담는다.
			request.setAttribute("encodedKeyword", encodedKeyword);
			request.setAttribute("keyword", keyword);
		}		
		//CafeDto 에 글번호도 담기
		dto.setNum(num);
		//조회수 1 증가 시키기
		cafeDao.addViewCount(num);
		//글정보를 얻어와서
		CafeDto dto2=cafeDao.getData(dto);
		//request 에 글정보를 담고 
		request.setAttribute("dto", dto2);
	}

Mapper

Mapper에서 

읽어올 글 정보(num, writer, title, content, viewCount, regdate,prevNum,nextNum)을 담은결과dto를 얻어내기위하여 getData코드를 작성해준다. service에서 보낸 dto를 인자로 갖는다.

이때 받아온 dto의 title,content,writer를 활용하여 검색어가 있다면 반영시

	<select id="getData" parameterType="cafeDto"
		resultType="cafeDto">
		SELECT result1.*
		FROM
			(SELECT num, writer, title, content, viewCount, 
			TO_CHAR(regdate, 'YY.MM.DD HH24:MI') AS regdate,
			LAG(num, 1, 0) OVER(ORDER BY num DESC) AS prevNum,
			LEAD(num, 1, 0) OVER(ORDER BY num DESC) AS nextNum
			FROM board_cafe
			<choose>
				<when test="title != null and content != null">
					WHERE title LIKE '%'||#{title}||'%' OR
					content  LIKE '%'||#{content}||'%'
				</when>
				<when test="title != null">
					WHERE title LIKE '%'||#{title}||'%'
				</when>
				<when test="writer != null">
					WHERE writer LIKE '%'||#{writer}||'%'
				</when>
			</choose>
			ORDER BY num DESC) result1
		WHERE num=#{num }
	</select>

 

참고: 글번호가 큰 순서(최신 작성된순서)대로 출력하고 있다.

       LAG(뒤떨어지다)- 이전 글(글 번호가 더 큰글-더 오래된 글)

       LEAD(이끌다)- 다음 글(글 번호가 더 작은글-더 최근 작성한 글)

       ex)아래의 글 목록에서 글번호 11의 이전글:12 이후글:10