[B -2-48] Ajax 댓글 처리 21 : [댓글의 페이징 처리]

2019. 10. 9. 14:48Project B (SPMS)/Project B 파트5

반응형

현재까지 작성된 게시글의 전체 댓글을 가져와서 화면에 출력한다.

문제는 댓글의 숫자가 엄청나게 많을 경우이다.

댓글의 숫자가 많다면 데이터베이스에서 많은 양의 데이터를 갖고와야 하고, 이는 성능상에 엄청난 문제를 야기한다.

일반적으로 이런 문제를 페이징 처리를 이용해서 처리한다.

 


데이터베이스의 인덱스 설계

 

인덱스 작성

create index IDX_REPLY
on TBL_REPLY (BNO desc, RNO desc);

댓글에 대해서 우선적으로 고려해야 하는 일은 TBL_REPLY 테이블을 접근할 때 댓글의 번호(rno)가 중심이 아니라, 게시물의 번호(bno)가 중심이 된다는 점이다.

데이터가 많아지면 성능에 문제가 발생할 수 있기때문에,

효율을 높이고 싶다면, 게시물의 번호에 맞게 댓글들을 모아서 빠르게 찾을 수 있는 구조로 만드는게 좋다.


댓글의 페이징 SQL 작성 

 

src/main/resources

com

spms

mapper

ReplyMapper.xml

getListWithPaging()

...더보기
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spms.mapper.ReplyMapper">
	
	<insert id="insert">
		insert into TBL_REPLY (
			RNO, BNO, REPLY, REPLYER
		)
		values (
			SEQ_REPLY.NEXTVAL, #{bno}, #{reply}, #{replyer}
		)
		
	</insert>
	
	<select id="read" resultType="com.spms.domain.ReplyVO">
		select *
		from TBL_REPLY
		WHERE RNO = #{rno}
	</select>
	
	<delete id="delete">
		delete from TBL_REPLY
		where RNO = #{rno}
	</delete>
	
	<update id="update">
		update TBL_REPLY
		set REPLY = #{reply},
			UPDATEDATE = SYSDATE
		where RNO = #{rno}
	</update>
	
	<select id="getListWithPaging" resultType="com.spms.domain.ReplyVO">
	<![CDATA[
   		select  RNO, BNO, REPLY, REPLYER, REPLYDATE, UPDATEDATE
		from 
		(
			select /*+ INDEX (TBL_REPLY IDX_REPLY) */ 
				rownum RNUM,  RNO, BNO, REPLY, REPLYER, REPLYDATE, UPDATEDATE
			from TBL_REPLY
			where BNO =  #{bno}
				and RNO > 0
				and rownum <= #{cri.pageNum} * #{cri.amount}
		) 
		where RNUM > (#{cri.pageNum} -1) * #{cri.amount}
	]]>
	</select>
	
</mapper>

 

getListWithPaging()

인덱스를 이용하는 이유중에 하나는 정렬을 피할 수 있기때문이다. 

 


테스트 코드 작성

 

src/test/java

com.spms.mapper

ReplyMapperTests.java

 

...더보기
package com.spms.mapper;

import java.util.List;
import java.util.stream.IntStream;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.spms.domain.Criteria;
import com.spms.domain.ReplyVO;

import lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {com.spms.config.RootConfig.class} )
@Log4j
public class ReplyMapperTests {

	private Long[] bnoArr = { 524313L, 524312L, 524311L, 524310L, 524309L };
	
	@Setter(onMethod_ = @Autowired)
	private ReplyMapper replyMapper;
	
	
	public void testMapper() {
		log.info(replyMapper);
	}
	
	
	public void testCreate() {
		IntStream.rangeClosed(1, 10).forEach(i -> {
			ReplyVO replyVO = new ReplyVO();
			replyVO.setBno(bnoArr[i % 5]);
			replyVO.setReply("댓글 테스트! " + i);
			replyVO.setReplyer("작성자" + i);
			replyMapper.insert(replyVO);
		});
	}
	
	
	public void testRead() {
		Long targetRno = 5L;
		ReplyVO replyVO = replyMapper.read(targetRno);
		log.info(replyVO);
	}
	
	
	public void testDelete() {
		Long targetRno = 7L;
		replyMapper.delete(targetRno);
	}
	
	public void testUpdate() {
		Long targetRno = 10L;
		ReplyVO replyVo = replyMapper.read(targetRno);
		replyVo.setReply("Update Reply");
		int count = replyMapper.update(replyVo);
		log.info("UPDATE COUNT : " + count);
	}
	
		
	public void testList() {
		Criteria cri = new Criteria();
		List<ReplyVO> replies = replyMapper.getListWithPaging(cri, bnoArr[0]);
		replies.forEach(reply -> log.info(reply));
		
	}
	
	// 524314L
	@Test
	public void testList2() {
		Criteria cri = new Criteria(1,10);
		List<ReplyVO> replies = replyMapper.getListWithPaging(cri, 524314L);
		replies.forEach(reply -> log.info(reply));
	}
	
}

 

게시글 번호 (524314) 번에 대한 게시글의 1페이지에 해당하는 10개의 글을 보여주는 기능을 테스트한다.

반응형