YJ의 새벽

Spring 16 ( pagination + 게시글조회 + 조회수증가(중복x)) 본문

Spring/Spring

Spring 16 ( pagination + 게시글조회 + 조회수증가(중복x))

YJDawn 2023. 5. 2. 16:20

 

 

 

--- 페이지 이동을 해보자 .

 

 

 

 

-- boardList.jsp    수정 .

 

--- 넘어가는것을 확인 .

 

 

 

 

 

 

---- 상세 게시글 조회를 해보자 .  

 

--- boardList.jsp  에서  경로 설정 . 

 

 

--- BoardController  ,  컨트롤러 클래스

 

 

 

 

---- BoardService .  서비스 클래스 

 

 

 

--- BoardDAO   .   DB접근 클래스 

 

 

--- board-mapper.xml    쿼리문 작성 . 

	<!-- 게시글 목록용 resultMap -->
	<resultMap type="board" id="board_rm">
		<id property="boardNo" column="BOARD_NO" />
		<result property="boardTitle" column="BOARD_TITLE" />
		<result property="createDate" column="CREATE_DT" />
		<result property="readCount" column="READ_COUNT" />
		<result property="memberNickname" column="MEMBER_NICK" />
		<result property="thumbnail" column="THUMBNAIL" />
	</resultMap>

	<!-- 게시글 상세 조회용 resultMap -->
	<resultMap type="detail" id="detail_rm">
		<id property="boardNo" column="BOARD_NO" />
		<result property="boardTitle" column="BOARD_TITLE" />
		<result property="boardContent" column="BOARD_CONTENT" />
		<result property="createDate" column="CREATE_DT" />
		<result property="updateDate" column="UPDATE_DT" />
		<result property="readCount" column="READ_COUNT" />
		<result property="memberNickname" column="MEMBER_NICK" />
		<result property="memberNo" column="MEMBER_NO" />
		<result property="profileImage" column="PROFILE_IMG" />
		<result property="boardName" column="BOARD_NM" />

		<collection property="imageList" column="BOARD_NO"
			javaType="java.util.ArrayList" ofType="boardImage"
			select="selectImageList" />
	</resultMap>
	
	<!-- 이미지 정보 조회용 resultMap -->
	<resultMap type="boardImage" id="boardImage_rm">
		<id property="imageNo" column="IMG_NO" />
		<result property="imageReName" column="IMG_RENAME" />
		<result property="imageOriginal" column="IMG_ORIGINAL" />
		<result property="imageLevel" column="IMG_LEVEL" />
		<result property="boardNo" column="BOARD_NO" />
	</resultMap>


	<!-- 특정 게시글 이미지 목록 조회 -->
	<select id="selectImageList" resultMap="boardImage_rm">
		SELECT * FROM BOARD_IMG
		WHERE BOARD_NO = #{boardNo}
		ORDER BY IMG_LEVEL
	</select>
    
    	<!-- 게시글 상세 조회 -->
	<select id="selectBoardDetail" resultMap="detail_rm">
		SELECT BOARD_NO,
		BOARD_TITLE, BOARD_CONTENT,
		TO_CHAR(CREATE_DT, 'YYYY"년" MM"월" DD"일"
		HH24:MI:SS') CREATE_DT,
		TO_CHAR(UPDATE_DT, 'YYYY"년" MM"월" DD"일"
		HH24:MI:SS') UPDATE_DT,
		READ_COUNT, MEMBER_NICK, MEMBER_NO,
		PROFILE_IMG,
		BOARD_NM
		FROM BOARD
		JOIN MEMBER_S USING(MEMBER_NO)
		JOIN
		BOARD_TYPE USING(BOARD_CD)
		WHERE BOARD_NO = ${boardNo}
		AND BOARD_ST =
		'N'
	</select>

--- selectImageList의 조회 결과를

    BoardDetail VO 의 imageList  필드에  담겠다 .

     -- imageList 에 담기위한 ArrayList<BoardImage> 객체를 생성

                (  javaType="java.util.ArrayList" ofType="boardImage"  )

    -- selectImageList 태그 수행 시 필요한 파라미터

       현재 resultMap (detail_rm ) 의 BOARD_NO 컬럼에 저장된 값을 전달하겠다.

 

--  즉 , 게시글 상세 조회 후 detail_rm  resultMap 이 호출되었을때.

           상세 조회 결과중 BOARD_NO 를 이용해서 selectImageList 를 수행하고

           결과를 imageList 필드에 세팅한다. 

        

 

 

 

 

 

 

 

 

 

 

 

 

 

 

------조회수 증가 시켜보자 .  

-- 기존 게시글 상세조회부분에  조회했을때, 조회수 증가되도록, 코드추가

// 게시글 상세 조회 
@GetMapping("/detail/{boardCode}/{boardNo}")
public String boardDetail( @PathVariable("boardCode") int boardCode, 
                           @PathVariable("boardNo") int boardNo,
                           @RequestParam(value = "cp", required = false, defaultValue = "1") int cp,
                           Model model ,
                           HttpSession session,
                           HttpServletRequest req,
                           HttpServletResponse resp  ) {
    //게시글 상세 조회 서비스 호출
    BoardDetail detail = service.selectBoardDetail(boardNo);

    // @ModelAttribute 는 별도의 required 속성이 없어서 무조건 필수 !! 
    //         --> 세션에 loginMember 가 없으면 예외 발생
    // 해결방법 : HttpSession  이용 

    //   상세 조회 성공시
    // 쿠키를 이용한 조회수 중복 증가 방지 코드 + 본인의 글은 조회수 증가 X 

    if ( detail != null ) {   //  상세조회를 했을경우

        Member loginMember = (Member) session.getAttribute("loginMember");  // 로그인멤버 찾아서

        int memberNo = 0;   // 현재 로그인한멤버와, 글쓴멤버가 같은지 체크 하기위한 변수초기화

        if ( loginMember != null ) {          // 로그인했으면 ???
            memberNo = loginMember.getMemberNo();    
        }
        if ( detail.getMemberNo() != memberNo ) {  // 글쓴이와 로그인한 사람이 같지 않은경우 조회수증가
            Cookie cookie = null ;               // 기존에 존재하던 쿠키를 저장하는 변수
            Cookie[] cookies = req.getCookies(); // 저장되있는 쿠키 싹 다 얻어오기

            if ( cookies != null && cookies.length > 0 ) {    // 얻어온쿠키가 있을 경우
                // 얻어온 쿠키중 이름이 "readBoardNo" 가 있으면 얻어오기.
                for ( Cookie c : cookies) {
                    if ( c.getName().equals("readBoardNo")) {
                        cookie = c;
                    }
                }
            }
            int result=0;

            if ( cookie == null ) {      // "readBoardNo" 쿠키가 없을 경우
                cookie = new Cookie("readBoardNo",boardNo+"");  
                result = service.updateReadCount(boardNo);   // 조회수증가 서비스호출

            }else {            // 기존에 "readBoardNo" 쿠키가 있을 경우
                //--> 쿠키에 저장된 값 뒤쪽에 현재 조회된 게시글 번호를 추가 
                // 단, 기존 쿠키값에 중복되는 번호가 없어야한다 !!!

                String[] temp = cookie.getValue().split("/");
                // "readBoardNo"  :  "1/2/11/10/20/300/1000"  == [1,2,11,20,300,1000]
                List<String> list = Arrays.asList(temp);   //  배열 --> List 변환

                // List.indexOf(Object) 
                // -- List에서 Object 와 일치하는 부분의 인덱스 반환,  없으면 -1 

                if ( list.indexOf( boardNo+"") == -1 ) {  // 기존값에 같은글번호가 없다면 추가
                    cookie.setValue( cookie.getValue() +"/"+ boardNo );
                    result = service.updateReadCount(boardNo);   // 조회수증가 서비스호출
                }
            }
            if ( result > 0 ) {   // 결과값 이용한 DB 동기화
                detail.setReadCount(detail.getReadCount()+1);   // 이미 조회된 데이터 DB동기화
                cookie.setPath(req.getContextPath());
                cookie.setMaxAge(60 * 60 * 1);
                resp.addCookie(cookie);
            }
        }
    }
    model.addAttribute("detail",detail);
    return "board/boardDetail";
}

 

 

 

 

--- BoardService 서비스클래스 .

 

 

 

--- BoardDAO   ,  db 연결 DAO 클래스.

 

 

--- board-mapper.xml   쿼리문

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Comments